Deprecate navilink, sbn, sbp. (#1138)
authorRobert Lipe <robertlipe@users.noreply.github.com>
Wed, 19 Jul 2023 11:01:24 +0000 (06:01 -0500)
committerGitHub <noreply@github.com>
Wed, 19 Jul 2023 11:01:24 +0000 (05:01 -0600)
As discussed in
https://github.com/GPSBabel/gpsbabel/pull/1090
these units have long since been deprecated by their maker. We have no
known remaining users. Numerous attempts (including  phone calls and
attempt to contact via the windsurfing community) to reach the last
known users have all failed.

Buh Bye.

27 files changed:
CMakeLists.txt
deprecated/navilink.cc [new file with mode: 0644]
deprecated/navilink.h [new file with mode: 0644]
deprecated/sbn.cc [new file with mode: 0644]
deprecated/sbp.cc [new file with mode: 0644]
navilink.cc [deleted file]
navilink.h [deleted file]
reference/format0.txt
reference/format1.txt
reference/format2.txt
reference/format3.txt
reference/help.txt
reference/navilink_tracks.gpx [deleted file]
reference/navilink_tracks.trk [deleted file]
reference/navilink_tracks_gpx.trk [deleted file]
reference/navilink_waypoints.gpx [deleted file]
reference/navilink_waypoints.wpt [deleted file]
reference/navilink_waypoints_gpx.wpt [deleted file]
sbn.cc [deleted file]
sbp.cc [deleted file]
testo.d/navilink.test [deleted file]
testo.d/sbn.test [deleted file]
testo.d/sbp.test [deleted file]
vecs.cc
xmldoc/formats/navilink.xml [deleted file]
xmldoc/formats/sbn.xml [deleted file]
xmldoc/formats/sbp.xml [deleted file]

index 02ef0a5f650b4c28b6b0ce379e4f44fed74c6132..ef11c2de0e69963ee0a56aafc7e1de460567c38f 100644 (file)
@@ -94,13 +94,10 @@ set(ALL_FMTS ${MINIMAL_FMTS}
   igc.cc
   lowranceusr.cc
   mtk_logger.cc
-  navilink.cc
   osm.cc
   ozi.cc
   qstarz_bl_1000.cc
   random.cc
-  sbn.cc
-  sbp.cc
   shape.cc
   skytraq.cc
   subrip.cc
@@ -228,7 +225,6 @@ set(HEADERS
   legacyformat.h
   igc.h
   lowranceusr.h
-  navilink.h
   nmea.h
   osm.h
   qstarz_bl_1000.h
@@ -400,7 +396,6 @@ set(TESTS
   lowranceusr
   mtk
   multiurlgpx
-  navilink
   nmea
   osm
   ozi
@@ -411,8 +406,6 @@ set(TESTS
   realtime
   resample
   route_reverse
-  sbn
-  sbp
   serialization
   shape
   simplify-relative
diff --git a/deprecated/navilink.cc b/deprecated/navilink.cc
new file mode 100644 (file)
index 0000000..c97ed13
--- /dev/null
@@ -0,0 +1,1220 @@
+/*
+    NaviGPS serial protocol.
+
+    Copyright (C) 2007 Tom Hughes, tom@compton.nu
+    Copyright (C) 2008 Rodney Lorrimar, rodney@rodney.id.au
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ */
+
+
+/* Based on description at http://wiki.splitbrain.org/navilink */
+
+#include <cstdio>                  // for fprintf, stderr
+#include <cstring>                 // for memcpy, memset, strncpy
+
+#include <QByteArray>              // for QByteArray
+#include <QDate>                   // for QDate
+#include <QDateTime>               // for QDateTime
+#include <QString>                 // for QString, operator==
+#include <QThread>                 // for QThread
+#include <QTime>                   // for QTime
+#include <QVector>                 // for QVector
+#include <QtCore>                  // for qRound, qPrintable, UTC
+
+#include "defs.h"
+#include "navilink.h"
+#include "gbfile.h"                // for gbfwrite, gbfclose, gbfopen, gbfread
+#include "gbser.h"                 // for gbser_read_wait, gbser_deinit, gbs...
+#include "jeeps/gpsmath.h"         // for GPS_Math_WGS84_To_UTM_EN
+#include "jeeps/gpsport.h"         // for int32
+#include "src/core/datetime.h"     // for DateTime
+
+
+#define MYNAME "NAVILINK"
+
+static char* nuketrk = nullptr;
+static char* nukerte = nullptr;
+static char* nukewpt = nullptr;
+static char* nukedlg = nullptr;
+static char* poweroff = nullptr;
+static char* datalog = nullptr;
+
+static void* serial_handle = nullptr;
+static gbfile* file_handle = nullptr;
+
+static unsigned char* track_data;
+static unsigned char* track_data_ptr;
+static unsigned char* track_data_end;
+static unsigned track_serial;
+static Waypoint** route_waypts;
+static unsigned* route_ids;
+static unsigned route_id_ptr;
+
+static enum {
+  READING,
+  WRITING
+} operation = READING;
+
+#define SERIAL_TIMEOUT        8000
+#define CLEAR_DATALOG_TIME    7000
+
+#define MAX_WAYPOINTS         1000
+#define MAX_SUBROUTES         9
+#define MAX_SUBROUTE_LENGTH   14
+#define MAX_ROUTE_LENGTH      (MAX_SUBROUTES * MAX_SUBROUTE_LENGTH - 1)
+#define MAX_READ_TRACKPOINTS  512
+#define MAX_WRITE_TRACKPOINTS 127
+#define MAX_READ_LOGPOINTS    256
+
+#define PID_SYNC              0xd6
+#define PID_ACK               0x0c
+#define PID_NAK               0x00
+#define PID_QRY_INFORMATION   0x20
+#define PID_QRY_FW_VERSION    0xfe
+#define PID_DATA              0x03
+#define PID_ADD_A_WAYPOINT    0x3c
+#define PID_QRY_WAYPOINTS     0x28
+#define PID_QRY_ROUTE         0x24
+#define PID_DEL_WAYPOINT      0x36
+#define PID_DEL_ALL_WAYPOINT  0x37
+#define PID_DEL_ROUTE         0x34
+#define PID_DEL_ALL_ROUTE     0x35
+#define PID_ADD_A_ROUTE       0x3d
+#define PID_ERASE_TRACK       0x11
+#define PID_READ_TRACKPOINTS  0x14
+#define PID_WRITE_TRACKPOINTS 0x16
+#define PID_CMD_OK            0xf3
+#define PID_CMD_FAIL          0xf4
+#define PID_QUIT              0xf2
+#define PID_INFO_DATALOG      0x1c
+#define PID_READ_DATALOG      0x14
+#define PID_CLEAR_DATALOG     0x1b
+
+static
+const char* const icon_table[] = {
+  "Star",
+  "Flag",
+  "House",
+  "Left Sign",
+  "Telegraph Pole",
+  "People",
+  "Fuel",
+  "Phone",
+  "Pole",
+  "Mountain",
+  "Water",
+  "Tree",
+  "Road Narrows",
+  "Crossroads",
+  "Road Fork",
+  "Turn Right",
+  "Turn Left",
+  "Bird",
+  "3D House",
+  "Trig Point",
+  "Tower",
+  "Cable Car",
+  "Church",
+  "Telegraph Pole",
+  "Skier",
+  "Anchor",
+  "Fish",
+  "Fishes",
+  "Rain",
+  "Fisherman",
+  "Tower",
+  "Boats",
+  "Boat",
+  "Bicycle",
+  "Railway Track",
+  "Dollar Sign",
+  "Bus",
+  "Camera",
+  "Fuel Pump",
+  "Cup",
+  "Merging Road",
+  "Plane",
+  "Red Cross",
+  "House",
+  "Parking"
+};
+
+static
+QVector<arglist_t> navilink_args = {
+  {
+    "nuketrk", &nuketrk, "Delete all track points", nullptr, ARGTYPE_BOOL,
+    ARG_NOMINMAX, nullptr
+  },
+  {
+    "nukerte", &nukerte, "Delete all routes", nullptr, ARGTYPE_BOOL,
+    ARG_NOMINMAX, nullptr
+  },
+  {
+    "nukewpt", &nukewpt, "Delete all waypoints", nullptr, ARGTYPE_BOOL,
+    ARG_NOMINMAX, nullptr
+  },
+  {
+    "nukedlg", &nukedlg, "Clear the datalog", nullptr, ARGTYPE_BOOL,
+    ARG_NOMINMAX, nullptr
+  },
+  {
+    "datalog", &datalog, "Read from datalogger buffer",
+    nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+  },
+  {
+    "power_off", &poweroff, "Command unit to power itself down",
+    nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+  },
+};
+
+static void (*write_waypoint)(const Waypoint*) = nullptr;
+static void (*write_track_start)(const route_head* track) = nullptr;
+static void (*write_track_point)(const Waypoint* waypt) = nullptr;
+static void (*write_track_end)(const route_head* track) = nullptr;
+static void (*write_route_start)(const route_head* track) = nullptr;
+static void (*write_route_point)(const Waypoint* waypt) = nullptr;
+static void (*write_route_end)(const route_head* track) = nullptr;
+
+static int
+find_icon_from_descr(const QString& descr)
+{
+  for (unsigned int i = 0; i < sizeof(icon_table) / sizeof(const char*); i++) {
+    if (0 == descr.compare(icon_table[i])) {
+      return i;
+    }
+  }
+
+  return 0;
+}
+
+static void
+free_waypoints(Waypoint** waypts)
+{
+  for (Waypoint** wayptp = waypts; wayptp < waypts + MAX_WAYPOINTS; wayptp++) {
+    if (*wayptp) {
+      delete *wayptp;
+    }
+  }
+
+  xfree(waypts);
+}
+
+static unsigned
+compare_waypoints(const Waypoint* waypt1, const Waypoint* waypt2)
+{
+  return waypt1->latitude == waypt2->latitude &&
+         waypt1->longitude == waypt2->longitude &&
+         waypt1->altitude == waypt2->altitude &&
+         waypt1->shortname == waypt2->shortname;
+}
+
+unsigned
+navilink_checksum_packet(const unsigned char* packet, unsigned length)
+{
+  unsigned checksum = 0;
+
+  while (length-- > 0) {
+    checksum += *packet++;
+  }
+
+  return checksum & 0x7fff;
+}
+
+static void
+dump_packet(const char* prefix, unsigned char* packet, unsigned length)
+{
+  unsigned i;
+
+  for (i = 0; i < length; i++) {
+    if ((i % 16) == 0) {
+      fprintf(stderr, "%s %08x :", prefix, i);
+    }
+    fprintf(stderr, " %02x", packet[i]);
+    if ((i % 16) == 15 || i == length - 1) {
+      fprintf(stderr, "\n");
+    }
+  }
+
+  fprintf(stderr, "\n");
+}
+
+static void
+write_packet(unsigned type, const void* payload, unsigned length)
+{
+  auto* packet = (unsigned char*) xmalloc(length + 9);
+
+  packet[0] = 0xa0;
+  packet[1] = 0xa2;
+  le_write16(packet + 2, length + 1);
+  packet[4] = type;
+  if (length > 0) {
+    memcpy(packet + 5, payload, length);
+  }
+  le_write16(packet + length + 5, navilink_checksum_packet(packet + 4, length + 1));
+  packet[length + 7] = 0xb0;
+  packet[length + 8] = 0xb3;
+
+  if (global_opts.debug_level >= 2) {
+    dump_packet(">>>", packet + 4, length + 1);
+  }
+
+  if (gbser_write(serial_handle, packet, length + 9) != gbser_OK) {
+    fatal(MYNAME ": Write error\n");
+  }
+
+  xfree(packet);
+}
+
+static unsigned
+read_word()
+{
+  unsigned char buffer[2];
+
+  if (gbser_read_wait(serial_handle, buffer, 2, SERIAL_TIMEOUT) != 2) {
+    fatal(MYNAME ": Read error\n");
+  }
+
+  return (buffer[1] << 8) | buffer[0];
+}
+
+/*
+ * Read a protocol packet into payload.
+ *
+ * handle_nak determines behaviour when a PID_NAK packet is read from
+ * the device:
+ *  - if handle_nak is false, a fatal error will be raised.
+ *  - if handle_nak is true, read_packet will simply return false.
+ *
+ * Returns true if the packet was successfully read into payload.
+ */
+static bool
+read_packet(unsigned type, void* payload,
+            int minlength, int maxlength,
+            bool handle_nak)
+{
+  if (read_word() != 0xa2a0) {
+    fatal(MYNAME ": Protocol error: Bad packet header."
+          " Is your NaviGPS in NAVILINK mode?\n");
+  }
+
+  int size;
+  if ((size = read_word()) <= minlength) {
+    fatal(MYNAME ": Protocol error: Packet too short\n");
+  }
+
+  auto* data = (unsigned char*) xmalloc(size);
+
+  if (gbser_read_wait(serial_handle, data, size, SERIAL_TIMEOUT) != size) {
+    fatal(MYNAME ": Read error reading %d byte payload\n", size);
+  }
+
+  if (global_opts.debug_level >= 2) {
+    dump_packet("<<<", data, size);
+  }
+
+  if (data[0] != type) {
+    if (handle_nak && data[0] == PID_NAK) {
+      return false;
+    }
+
+    fatal(MYNAME ": Protocol error: Bad packet type (expected 0x%02x but got 0x%02x)\n", type, data[0]);
+  }
+
+  unsigned checksum;
+  if ((checksum = read_word()) != navilink_checksum_packet(data, size)) {
+    fatal(MYNAME ": Checksum error - expected %x got %x\n",
+          navilink_checksum_packet(data, size), checksum);
+  }
+
+  if (read_word() != 0xb3b0) {
+    fatal(MYNAME ": Protocol error: Bad packet trailer\n");
+  }
+
+  if (size - 1 > maxlength) {
+    memcpy(payload, data + 1, maxlength);
+  } else {
+    memcpy(payload, data + 1, size - 1);
+  }
+
+  xfree(data);
+
+  return true;
+}
+
+static QDateTime
+decode_datetime(const unsigned char* buffer)
+{
+  QTime tm(buffer[3], buffer[4], buffer[5]);
+  QDate dt(2000 + buffer[0], buffer[1], buffer[2]);
+  return QDateTime(dt, tm, Qt::UTC);
+}
+
+static void
+encode_datetime(const QDateTime& datetime, unsigned char* buffer)
+{
+  if (datetime.isValid()) {
+    QDateTime dt = datetime.toUTC();
+    QDate date = dt.date();
+    QTime time = dt.time();
+    buffer[0] = date.year() - 2000;
+    buffer[1] = date.month();
+    buffer[2] = date.day();
+    buffer[3] = time.hour();
+    buffer[4] = time.minute();
+    buffer[5] = time.second();
+  } else {
+    memset(buffer, 0, 6);
+  }
+}
+
+static void
+decode_position(const unsigned char* buffer, Waypoint* waypt)
+{
+  waypt->latitude = le_read32(buffer + 0) / 10000000.0;
+  waypt->longitude = le_read32(buffer + 4) / 10000000.0;
+  waypt->altitude = FEET_TO_METERS(le_read16(buffer + 8));
+}
+
+static void
+encode_position(const Waypoint* waypt, unsigned char* buffer)
+{
+  le_write32(buffer + 0, qRound(waypt->latitude * 10000000));
+  le_write32(buffer + 4, qRound(waypt->longitude * 10000000));
+  le_write16(buffer + 8, qRound(METERS_TO_FEET(waypt->altitude)));
+}
+
+static unsigned
+decode_waypoint_id(const unsigned char* buffer)
+{
+  unsigned id = le_read16(buffer + 2);
+
+  if (id >= MAX_WAYPOINTS) {
+    fatal(MYNAME ": Invalid waypoint ID\n");
+  }
+
+  return id;
+}
+
+static Waypoint*
+decode_waypoint(const unsigned char* buffer)
+{
+  auto* waypt = new Waypoint;
+
+  decode_position(buffer + 12, waypt);
+  waypt->shortname = reinterpret_cast<const char*>(buffer) + 4;
+  waypt->icon_descr = icon_table[buffer[28]];
+  waypt->SetCreationTime(decode_datetime(buffer + 22));
+
+  return waypt;
+}
+
+static void
+encode_waypoint(const Waypoint* waypt, unsigned char* buffer)
+{
+  buffer[0] = 0x00;
+  buffer[1] = 0x40;
+  le_write16(buffer + 2, 0);
+  strncpy((char*)buffer + 4, CSTRc(waypt->shortname), 6);
+  buffer[10] = 0;
+  buffer[11] = 0;
+  encode_position(waypt, buffer + 12);
+  encode_datetime(waypt->GetCreationTime(), buffer + 22);
+  buffer[28] = find_icon_from_descr(waypt->icon_descr);
+  buffer[29] = 0;
+  buffer[30] = 0x00;
+  buffer[31] = 0x7e;
+}
+
+static Waypoint*
+decode_trackpoint(const unsigned char* buffer)
+{
+  auto* waypt = new Waypoint;
+
+  decode_position(buffer + 12, waypt);
+  waypt->SetCreationTime(decode_datetime(buffer + 22));
+  waypt->set_course(le_read16(buffer + 2));
+  waypt->set_speed(KPH_TO_MPS(buffer[29] * 2));
+
+  return waypt;
+}
+
+static void
+encode_trackpoint(const Waypoint* waypt, unsigned serial, unsigned char* buffer)
+{
+  double x;
+  double y;
+  int32  z;
+  char   zc;
+
+  GPS_Math_WGS84_To_UTM_EN(waypt->latitude, waypt->longitude, &x, &y, &z, &zc);
+
+  le_write16(buffer + 0, serial);
+  le_write16(buffer + 2, qRound(waypt->course_value_or(0)));
+  le_write32(buffer + 4, qRound(x));
+  le_write32(buffer + 8, qRound(y));
+  encode_position(waypt, buffer + 12);
+  encode_datetime(waypt->GetCreationTime(), buffer + 22);
+  buffer[28] = z;
+  buffer[29] = qRound(MPS_TO_KPH(waypt->speed_value_or(0) / 2));
+  buffer[30] = 0x5a;
+  buffer[31] = 0x7e;
+}
+
+static Waypoint**
+serial_read_waypoints()
+{
+  Waypoint**       waypts = nullptr;
+  unsigned char  information[32];
+
+  if (global_opts.masked_objective & RTEDATAMASK) {
+    waypts = (Waypoint**) xcalloc(MAX_WAYPOINTS, sizeof(Waypoint*));
+  }
+
+  write_packet(PID_QRY_INFORMATION, nullptr, 0);
+  read_packet(PID_DATA, information,
+              sizeof(information), sizeof(information),
+              false);
+
+  unsigned short total = le_read16(information + 0);
+
+  for (unsigned short start = 0; start < total; start += 32) {
+    unsigned short count = total - start;
+    unsigned char  payload[7];
+
+    if (count > 32) {
+      count = 32;
+    }
+
+    le_write32(payload + 0, start);
+    le_write16(payload + 4, count);
+    payload[6] = 1;
+
+    write_packet(PID_QRY_WAYPOINTS, payload, sizeof(payload));
+
+    auto*  waypoints = (unsigned char*) xmalloc(count * 32);
+
+    read_packet(PID_DATA, waypoints, count * 32, count * 32, false);
+
+    for (unsigned char*  w = waypoints; w < waypoints + count * 32; w = w + 32) {
+      if (global_opts.masked_objective & WPTDATAMASK) {
+        waypt_add(decode_waypoint(w));
+      }
+      if (global_opts.masked_objective & RTEDATAMASK) {
+        waypts[decode_waypoint_id(w)] = decode_waypoint(w);
+      }
+    }
+
+    xfree(waypoints);
+
+    if (global_opts.verbose_status) {
+      waypt_status_disp(total, start + count);
+    }
+  }
+
+  return waypts;
+}
+
+static unsigned int
+serial_write_waypoint_packet(const Waypoint* waypt)
+{
+  unsigned char data[32];
+  unsigned char id[2];
+
+  encode_waypoint(waypt, data);
+  write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data));
+  if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), true)) {
+    fatal(MYNAME ": Could not write waypoint.\n");
+  }
+
+  return le_read16(id);
+}
+
+static void
+serial_write_waypoint(const Waypoint* waypt)
+{
+  serial_write_waypoint_packet(waypt);
+}
+
+static void
+serial_read_track()
+{
+  unsigned char  information[32];
+
+  write_packet(PID_QRY_INFORMATION, nullptr, 0);
+  read_packet(PID_DATA, information,
+              sizeof(information), sizeof(information),
+              false);
+
+  unsigned int address = le_read32(information + 4);
+  unsigned short total = le_read16(information + 12);
+
+  auto* track = new route_head;
+  track_add_head(track);
+
+  while (total > 0) {
+    unsigned short count = total < MAX_READ_TRACKPOINTS ? total : MAX_READ_TRACKPOINTS;
+    unsigned char  payload[7];
+
+    le_write32(payload + 0, address);
+    le_write16(payload + 4, count * 32);
+    payload[6] = 0x00;
+
+    write_packet(PID_READ_TRACKPOINTS, payload, sizeof(payload));
+
+    auto*  trackpoints = (unsigned char*) xmalloc(count * 32);
+
+    read_packet(PID_DATA, trackpoints, count * 32, count * 32, false);
+    write_packet(PID_ACK, nullptr, 0);
+
+    for (unsigned char*  t = trackpoints; t < trackpoints + count * 32; t = t + 32) {
+      track_add_wpt(track, decode_trackpoint(t));
+    }
+
+    xfree(trackpoints);
+
+    address = address + count * 32;
+    total = total - count;
+  }
+}
+
+static void
+serial_write_track()
+{
+  unsigned char  information[32];
+  unsigned char  data[7];
+
+  write_packet(PID_QRY_INFORMATION, nullptr, 0);
+  read_packet(PID_DATA, information,
+              sizeof(information), sizeof(information),
+              false);
+
+  unsigned int address = le_read32(information + 4);
+  unsigned short total = le_read16(information + 12);
+
+  le_write32(data + 0, address + total * 32);
+  le_write16(data + 4, track_data_ptr - track_data);
+  data[6] = 0x00;
+
+  write_packet(PID_WRITE_TRACKPOINTS, data, sizeof(data));
+  QThread::usleep(10000);
+  write_packet(PID_DATA, track_data, track_data_ptr - track_data);
+  read_packet(PID_CMD_OK, nullptr, 0, 0, false);
+
+  track_data_ptr = track_data;
+}
+
+static void
+serial_write_track_start(const route_head*)
+{
+  track_data = (unsigned char*) xmalloc(MAX_WRITE_TRACKPOINTS * 32);
+  track_data_ptr = track_data;
+  track_data_end = track_data + MAX_WRITE_TRACKPOINTS * 32;
+}
+
+static void
+serial_write_track_point(const Waypoint* waypt)
+{
+  if (track_data_ptr >= track_data_end) {
+    serial_write_track();
+  }
+
+  encode_trackpoint(waypt, 0, track_data_ptr);
+
+  track_data_ptr += 32;
+}
+
+static void
+serial_write_track_end(const route_head*)
+{
+  if (track_data_ptr > track_data) {
+    serial_write_track();
+  }
+
+  xfree(track_data);
+}
+
+static void
+serial_read_routes(Waypoint** waypts)
+{
+  unsigned char information[32];
+
+  write_packet(PID_QRY_INFORMATION, nullptr, 0);
+  read_packet(PID_DATA, information,
+              sizeof(information), sizeof(information),
+              false);
+
+  unsigned char routec = information[2];
+
+  for (unsigned char r = 0; r < routec; r++) {
+    unsigned char payload[7];
+    unsigned char routedata[320];
+
+    le_write32(payload + 0, r);
+    le_write16(payload + 2, 0);
+    payload[6] = 0x01;
+
+    write_packet(PID_QRY_ROUTE, payload, sizeof(payload));
+    read_packet(PID_DATA, routedata, 64, sizeof(routedata), false);
+
+    auto* route = new route_head;
+    route->rte_num = routedata[2];
+    route->rte_name = (char*)routedata + 4;
+    route_add_head(route);
+
+    for (int sr = 0; sr < MAX_SUBROUTES; sr++) {
+      for (int w = 0; w < MAX_SUBROUTE_LENGTH; w++) {
+        unsigned short id = le_read16(routedata + 34 + 32 * sr + 2 *w);
+
+        if (id == 0xffffu) {
+          w = MAX_SUBROUTE_LENGTH;
+          sr = MAX_SUBROUTES;
+        } else if (id >= MAX_WAYPOINTS) {
+          fatal(MYNAME ": Invalid waypoint ID in route\n");
+        } else if (waypts[id] == nullptr) {
+          fatal(MYNAME ": Non-existent waypoint in route\n");
+        } else {
+          route_add_wpt(route, new Waypoint(*waypts[id]));
+        }
+      }
+    }
+  }
+}
+
+static void
+serial_write_route_start(const route_head* route)
+{
+  route_ids = (unsigned int*) xmalloc(route->rte_waypt_ct() * sizeof(unsigned));
+  route_id_ptr = 0;
+}
+
+static void
+serial_write_route_point(const Waypoint* waypt)
+{
+  unsigned w;
+
+  for (w = 0; w < MAX_WAYPOINTS; w++) {
+    if (route_waypts[w] && compare_waypoints(waypt, route_waypts[w])) {
+      break;
+    }
+  }
+
+  if (w == MAX_WAYPOINTS) {
+    w = serial_write_waypoint_packet(waypt);
+    route_waypts[w] = new Waypoint(*waypt);
+  }
+
+  route_ids[route_id_ptr++] = w;
+}
+
+static void
+serial_write_route_end(const route_head* route)
+{
+  unsigned char id[1];
+
+  QString rte_name = route->rte_name;
+  if (rte_name == nullptr) {
+    rte_name = "NO NAME";
+  }
+  if (route_id_ptr > MAX_ROUTE_LENGTH) {
+    fatal(MYNAME ": Route %s too long\n", qPrintable(route->rte_name));
+  }
+
+  unsigned src = (route_id_ptr + MAX_SUBROUTE_LENGTH) / MAX_SUBROUTE_LENGTH;
+  auto* data = (unsigned char*) xmalloc(32 + src * 32);
+
+  le_write16(data + 0, 0x2000);
+  data[2] = 0;
+  data[3] = 0x20;
+  memset(data + 4, 0, 14);
+  strncpy((char*)data + 4, CSTR(rte_name), 13);
+  data[18] = 0;
+  data[19] = 0;
+  le_write32(data + 20, 0);
+  le_write32(data + 24, 0);
+  le_write16(data + 28, 0);
+  data[30] = 0x7b;
+  data[31] = 0x77;
+
+  for (unsigned sr = 0; sr < src; sr++) {
+    unsigned char* srdata = data + 32 + 32 * sr;
+    unsigned      pt_offset = MAX_SUBROUTE_LENGTH * sr;
+
+    le_write16(srdata + 0, 0x2010);
+
+    for (unsigned pt = 0; pt < MAX_SUBROUTE_LENGTH; pt++) {
+      if (pt_offset + pt < route_id_ptr) {
+        le_write16(srdata + 2 + 2 * pt, route_ids[pt_offset + pt]);
+      } else {
+        le_write16(srdata + 2 + 2 * pt, 0xffffu);
+      }
+    }
+
+    srdata[30] = 0x7f;
+    srdata[31] = 0x77;
+  }
+
+  write_packet(PID_ADD_A_ROUTE, data, 32 + src * 32);
+  if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), true)) {
+    fatal(MYNAME ": Could not add route.\n");
+  }
+
+  xfree(data);
+  xfree(route_ids);
+}
+
+static int
+decode_sbp_msec(const unsigned char* buffer)
+{
+  int msec = le_read16(buffer);
+  return (msec % 1000);
+}
+
+static QDateTime
+decode_sbp_datetime_packed(const unsigned char* buffer)
+{
+  /*
+   * Packed_Date_Time_UTC:
+   *   bit 31..22 :year*12+month (10 bits) :   real year= year+2000
+   *   bit17.21: day (5bits)
+   *   bit12.16: hour (5bits)
+   *   bit6..11: min  (6bits)
+   *   bit0..5 : sec  (6bits)
+   *
+   * 0        1        2        3
+   * 01234567 01234567 01234567 01234567
+   * ........ ........ ........ ........
+   * SSSSSSMM MMMMHHHH Hdddddmm mmmmmmmm
+   */
+
+  int sec = buffer[0] & 0x3F;
+  int min = ((buffer[0] & 0xC0) >> 6) | ((buffer[1] & 0x0F) << 2);
+  int hour = ((buffer[1] & 0xF0) >> 4) | ((buffer[2] & 0x01) << 4);
+  int mday = (buffer[2] & 0x3E) >> 1;
+  int months = ((buffer[2] & 0xC0) >> 6) | buffer[3] << 2;
+  int mon = months % 12;
+  int year = 2000 + months / 12;
+
+  return {QDate(year, mon, mday), QTime(hour, min, sec), Qt::UTC};
+}
+
+static void
+decode_sbp_position(const unsigned char* buffer, Waypoint* waypt)
+{
+  waypt->latitude = le_read32(buffer + 0) / 10000000.0;
+  waypt->longitude = le_read32(buffer + 4) / 10000000.0;
+  waypt->altitude = le_read32(buffer + 8) / 100.0;
+}
+
+Waypoint*
+navilink_decode_logpoint(const unsigned char* buffer)
+{
+  auto* waypt = new Waypoint;
+
+  waypt->hdop = (buffer[0]) * 0.2f;
+  waypt->sat = buffer[1];
+  waypt->SetCreationTime(decode_sbp_datetime_packed(buffer + 4)
+                         .addMSecs(decode_sbp_msec(buffer + 2)));
+  decode_sbp_position(buffer + 12, waypt);
+  waypt->set_speed(le_read16(buffer + 24) * 0.01f);
+  waypt->set_course(le_read16(buffer + 26) * 0.01f);
+
+  return waypt;
+}
+
+/*
+ * The datalog is a circular buffer, so it may be necessary to glue
+ * together two segments. This function queries the device for the
+ * circular buffer pointers, and returns two pairs of address/length.
+ * If there is only one segment (i.e. the datalog has not yet wrapped
+ * around), then seg2_addr and seg2_len will be zero.
+ */
+static void
+read_datalog_info(unsigned int* seg1_addr, unsigned int* seg1_len,
+                  unsigned int* seg2_addr, unsigned int* seg2_len)
+{
+  unsigned char  info[16];
+
+  write_packet(PID_INFO_DATALOG, nullptr, 0);
+  read_packet(PID_DATA, info, sizeof(info), sizeof(info), false);
+
+  unsigned int flash_start_addr = le_read32(info);
+  unsigned int flash_length = le_read32(info + 4);
+  unsigned int data_start_addr = le_read32(info + 8);
+  unsigned int next_blank_addr = le_read32(info + 12);
+
+  if (data_start_addr > next_blank_addr) {
+    /* usually there are two segments to be read */
+    *seg1_addr = data_start_addr;
+    *seg1_len = flash_start_addr + flash_length - *seg1_addr;
+    *seg2_addr = flash_start_addr;
+    *seg2_len = next_blank_addr - flash_start_addr;
+  } else {
+    /* hasn't wrapped around yet, only one segment */
+    *seg1_addr = data_start_addr;
+    *seg1_len = next_blank_addr - data_start_addr;
+    *seg2_addr = 0;
+    *seg2_len = 0;
+  }
+
+  if (*seg1_len & 0x1F || *seg2_len & 0x1F) {
+    fatal(MYNAME ": Protocol error: datalog lengths %u, %u "
+          "not aligned to 32 bytes\n", *seg1_len, *seg2_len);
+  }
+}
+
+static void
+read_datalog_records(route_head* track,
+                     unsigned int start_addr, unsigned int len)
+{
+  unsigned char  payload[7];
+
+  /* The protocol only supports reading 256 logpoints at once, so
+   * read small chunks until none left. */
+  while (len > 0) {
+    unsigned char  logpoints[MAX_READ_LOGPOINTS * SBP_RECORD_LEN];
+    unsigned int   logpoints_len = len > MAX_READ_LOGPOINTS ? MAX_READ_LOGPOINTS : len;
+
+    le_write32(payload, start_addr);
+    le_write16(payload + 4, logpoints_len);
+    payload[6] = 0x01;
+
+    write_packet(PID_READ_DATALOG, payload, sizeof(payload));
+    read_packet(PID_DATA, logpoints, logpoints_len, logpoints_len, false);
+    write_packet(PID_ACK, nullptr, 0);
+
+    for (unsigned char* p = logpoints; p < logpoints + logpoints_len; p += 32) {
+      track_add_wpt(track, navilink_decode_logpoint(p));
+    }
+
+    len -= logpoints_len;
+    start_addr += logpoints_len;
+  }
+}
+
+static void
+serial_read_datalog()
+{
+  unsigned int seg1_addr;
+  unsigned int seg1_len;
+  unsigned int seg2_addr;
+  unsigned int seg2_len;
+
+  read_datalog_info(&seg1_addr, &seg1_len, &seg2_addr, &seg2_len);
+
+  auto* track = new route_head;
+  track_add_head(track);
+
+  if (seg1_len) {
+    read_datalog_records(track, seg1_addr, seg1_len);
+  }
+
+  if (seg2_len) {
+    read_datalog_records(track, seg2_addr, seg2_len);
+  }
+}
+
+static void
+file_read()
+{
+  unsigned char data[32];
+  route_head*    track = nullptr;
+
+  while (gbfread(data, sizeof(data), 1, file_handle) == 1) {
+    switch (le_read16(data)) {
+    case 0x2000:
+      fatal(MYNAME ": Route objects not supported in file sources\n");
+      break;
+    case 0x2010:
+      fatal(MYNAME ": Subroute objects not supported in file sources\n");
+      break;
+    case 0x4000:
+      if (global_opts.masked_objective & WPTDATAMASK) {
+        waypt_add(decode_waypoint(data));
+      }
+      break;
+    default:
+      if (global_opts.masked_objective & TRKDATAMASK) {
+        if (track == nullptr) {
+          track = new route_head;
+          track_add_head(track);
+        }
+
+        track_add_wpt(track, decode_trackpoint(data));
+      }
+      break;
+    }
+  }
+}
+
+static void
+file_write_waypoint(const Waypoint* waypt)
+{
+  unsigned char data[32];
+
+  encode_waypoint(waypt, data);
+  gbfwrite(data, sizeof(data), 1, file_handle);
+}
+
+static void
+file_write_track_start(const route_head*)
+{
+  track_serial = 1;
+}
+
+static void
+file_write_track_point(const Waypoint* waypt)
+{
+  unsigned char data[32];
+
+  encode_trackpoint(waypt, track_serial++, data);
+  gbfwrite(data, sizeof(data), 1, file_handle);
+}
+
+static void
+file_write_track_end(const route_head*)
+{
+}
+
+static void
+file_write_route_start(const route_head*)
+{
+  fatal(MYNAME ": Can't write routes to a file\n");
+}
+
+static void
+file_write_route_point(const Waypoint*)
+{
+}
+
+static void
+file_write_route_end(const route_head*)
+{
+}
+
+static void
+nuke()
+{
+  if (nuketrk) {
+    unsigned char information[32];
+    unsigned char data[7];
+
+    write_packet(PID_QRY_INFORMATION, nullptr, 0);
+    read_packet(PID_DATA, information,
+                sizeof(information), sizeof(information),
+                false);
+
+    le_write32(data + 0, le_read32(information + 4));
+    le_write16(data + 4, 0);
+    data[6] = 0;
+
+    write_packet(PID_ERASE_TRACK, data, sizeof(data));
+    read_packet(PID_CMD_OK, nullptr, 0, 0, false);
+  }
+
+  if (nukerte) {
+    unsigned char data[4];
+
+    le_write32(data, 0x00f00000);
+    write_packet(PID_DEL_ALL_ROUTE, data, sizeof(data));
+    if (!read_packet(PID_ACK, nullptr, 0, 0, true)) {
+      fatal(MYNAME ": Could not nuke all routes.\n");
+    }
+  }
+
+  if (nukewpt) {
+    unsigned char data[4];
+
+    le_write32(data, 0x00f00000);
+    write_packet(PID_DEL_ALL_WAYPOINT, data, sizeof(data));
+    if (!read_packet(PID_ACK, nullptr, 0, 0, true)) {
+      fatal(MYNAME ": You must nuke all routes before nuking waypoints.\n");
+      /* perhaps a better action would be to nuke routes for user.
+       * i.e. set nukerte when nukewpt is set */
+    }
+  }
+
+  if (nukedlg) {
+    write_packet(PID_CLEAR_DATALOG, nullptr, 0);
+    /* The flash erase operation is time-consuming. Each sector (64KB)
+     * takes around 1 second.  The total sectors for SBP is 10.
+     * So give the device some time to clear its datalog, in addition
+     * to SERIAL_TIMEOUT, which applies to read_packet() */
+    QThread::usleep(CLEAR_DATALOG_TIME * 1000);
+    read_packet(PID_ACK, nullptr, 0, 0, false);
+  }
+}
+
+static void
+navilink_common_init(const QString& name)
+{
+  if (gbser_is_serial(qPrintable(name))) {
+    if ((serial_handle = gbser_init(qPrintable(name))) == nullptr) {
+      fatal(MYNAME ": Could not open serial port %s\n", qPrintable(name));
+    }
+
+    if (gbser_set_port(serial_handle, 115200, 8, 0, 1) != gbser_OK) {
+      fatal(MYNAME ": Can't configure port\n");
+    }
+
+    write_packet(PID_SYNC, nullptr, 0);
+    read_packet(PID_ACK, nullptr, 0, 0, false);
+
+    /* nuke data before writing */
+    if (operation == WRITING) {
+      nuke();
+    }
+
+    write_waypoint = serial_write_waypoint;
+    write_track_start = serial_write_track_start;
+    write_track_point = serial_write_track_point;
+    write_track_end = serial_write_track_end;
+    write_route_start = serial_write_route_start;
+    write_route_point = serial_write_route_point;
+    write_route_end = serial_write_route_end;
+  } else {
+    const char* mode = operation == READING ? "r" : "wb";
+    file_handle = gbfopen(name, mode, MYNAME);
+
+    write_waypoint = file_write_waypoint;
+    write_track_start = file_write_track_start;
+    write_track_point = file_write_track_point;
+    write_track_end = file_write_track_end;
+    write_route_start = file_write_route_start;
+    write_route_point = file_write_route_point;
+    write_route_end = file_write_route_end;
+  }
+
+}
+
+static void
+navilink_rd_init(const QString& name)
+{
+  operation = READING;
+  navilink_common_init(name);
+}
+
+static void
+navilink_wr_init(const QString& name)
+{
+  operation = WRITING;
+  navilink_common_init(name);
+}
+
+static void
+navilink_deinit()
+{
+  if (serial_handle) {
+    /* nuke data after reading */
+    if (operation == READING) {
+      nuke();
+    }
+
+    if (poweroff) {
+      write_packet(PID_QUIT, nullptr, 0);
+    }
+
+    gbser_deinit(serial_handle);
+  }
+
+  if (file_handle) {
+    gbfclose(file_handle);
+  }
+
+}
+
+static void
+navilink_read()
+{
+  if (datalog) {
+    if (global_opts.masked_objective & TRKDATAMASK) {
+      if (serial_handle) {
+        serial_read_datalog();
+      } else if (file_handle) {
+        fatal(MYNAME ": Not supported. Use SBP format.\n");
+      }
+    }
+  } else {
+    if (serial_handle) {
+      Waypoint** waypts = nullptr;
+
+      if (global_opts.masked_objective & (WPTDATAMASK|RTEDATAMASK)) {
+        waypts = serial_read_waypoints();
+      }
+
+      if (global_opts.masked_objective & TRKDATAMASK) {
+        serial_read_track();
+      }
+
+      if (global_opts.masked_objective & RTEDATAMASK) {
+        serial_read_routes(waypts);
+      }
+
+      if (waypts) {
+        free_waypoints(waypts);
+      }
+    } else if (file_handle) {
+      file_read();
+    }
+  }
+}
+
+static void
+navilink_write()
+{
+  if (datalog)  {
+    fatal(MYNAME ": Writing to datalog not supported.\n");
+  }
+
+  switch (global_opts.objective) {
+  case trkdata:
+    track_disp_all(write_track_start,
+                   write_track_end,
+                   write_track_point);
+    break;
+  case wptdata:
+    waypt_disp_all(write_waypoint);
+    break;
+  case rtedata:
+    if (serial_handle) {
+      route_waypts = serial_read_waypoints();
+    }
+    route_disp_all(write_route_start,
+                   write_route_end,
+                   write_route_point);
+    if (route_waypts) {
+      free_waypoints(route_waypts);
+      route_waypts = nullptr;
+    }
+    break;
+  default:
+    fatal(MYNAME ": Unknown objective.\n");
+  }
+}
+
+ff_vecs_t navilink_vecs = {
+  ff_type_serial,
+  FF_CAP_RW_ALL,
+  navilink_rd_init,
+  navilink_wr_init,
+  navilink_deinit,
+  navilink_deinit,
+  navilink_read,
+  navilink_write,
+  nullptr,
+  &navilink_args,
+  NULL_POS_OPS
+};
diff --git a/deprecated/navilink.h b/deprecated/navilink.h
new file mode 100644 (file)
index 0000000..3f33e99
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+    Locosys NaviGPS GT-31/BGT-31 common functions.
+
+    Copyright (C) 2008  Rodney Lorrimar <rodney@rodney.id.au>
+    Copyright (C) 2005  Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ */
+
+#ifndef NAVILINK_H_INCLUDED_
+#define NAVILINK_H_INCLUDED_
+
+#include <ctime>
+#include "defs.h"
+
+#define SBP_RECORD_LEN 32
+
+/* defined in navilink.c */
+Waypoint* navilink_decode_logpoint(const unsigned char* buffer);
+unsigned navilink_checksum_packet(const unsigned char* packet, unsigned length);
+
+/* defined in sbn.c */
+bool locosys_decode_file_id(char* header, size_t len);
+
+
+#ifdef THIS_IS_ONLY_FOR_REFERENCE
+/* Locosys SBP and SBN structures */
+
+typedef __packed struct {
+  UINT8 HDOP;        /* HDOP [0..51] with resolution 0.2 */
+  UINT8 SVIDCnt;        /* Number of SVs in solution [0 to 12] */
+  UINT16 UtcSec;        /* UTC Second [0 to 59] in seconds with resolution 0.001 */
+  UINT32 date_time_UTC_packed; /* refer to protocol doc*/
+  UINT32 SVIDList;    /* SVs in solution:  Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */
+  INT32 Lat;            /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */
+  INT32 Lon;            /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */
+  INT32 AltCM;            /* Altitude from Mean Sea Level in centi meters */
+  UINT16 Sog;            /* Speed Over Ground in m/sec with resolution 0.01 */
+  UINT16 Cog;            /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */
+  INT16 ClmbRte;        /* Climb rate in m/sec with resolution 0.01 */
+  UINT8 bitFlags;     /* bitFlags, default 0x00,    bit 0=1 indicate the first point after power on */
+  UINT8 reserved;
+} T_SBP;
+
+typedef struct __packed {
+  UINT8 Mid;
+  UINT16 Valid;
+  UINT16 Mode;            /* Nav Mode:  bit map as follows:
+                            *  Bits 2-0:  GPS Fix Type
+                            *    000   =  No Nav
+                            *    001   =  1 SV solution
+                            *    010   =  2 SV solution
+                            *    011   =  3 SV solution (2D)
+                            *    100   =  4 or more SV solution (3D)
+                            *    101   =  Least Square 2D solution
+                            *    110   =  Least Square 3D solution
+                            *    111   =  DR solution (no SV)
+                            *  Bit  3  :  1 = Trickle Power ON
+                            *  Bits 5-4:  Altitude Hold
+                            *    00    =  No Altitude Hold
+                            *    01    =  Altitude Hold using altitude from KF
+                            *    10    =  Altitude Hold using altitude from user
+                            *    11    =  forced altitude
+                            *  Bit 6   :  1 = DOP exceeded
+                            *  Bit 7   :  1 = DGPS correction applied
+                            *  Bit 8   :
+                            *    1     = Sensor-based DR
+                            *    0     = Velocity DR, if bits 2-0 = 111
+                            *          = see bits 15-14, if bits 2-0 != 111
+                            *  Bit 9   :  1 = Solution validated
+                            *  Bit 10  :  1 = Velocity DR Timeout
+                            *  Bit 11  :  1 = Solution edited by UI
+                            *  Bit 12  :  1 = Velocity invalid
+                            *  Bit 13  :  1 = Altitude Hold disabled
+                            *  Bits 15-14: SiRFDrive DR Status (applicable only when bit 8=0)
+                            *    00    =  GPS Only
+                            *    01    =  Calibrating
+                            *    10    =  DR sensor error
+                            *    11    =  DR Test mode
+                            */
+  UINT16 Week;            /* Extended Week Number */
+  UINT32 TOW;             /* Time of Week [0 to 604800] in seconds with resolution 0.001 */
+  UINT16 UtcYr;           /* UTC Year   [1980 to 3000] */
+  UINT8  UtcMth;          /* UTC Month  [1 to 12] */
+  UINT8  UtcDay;          /* UTC Day    [1 to 31] */
+  UINT8  UtcHr;           /* UTC Hour   [0 to 23] */
+  UINT8  UtcMin;          /* UTC Minute [0 to 59] */
+  UINT16 UtcSec;          /* UTC Second [0 to 59] in seconds with resolution 0.001 */
+  UINT32 SVIDList;        /* SVs in solution:  Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */
+
+  INT32  Lat;             /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */
+  INT32  Lon;             /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */
+  INT32  AltE;            /* Altitude from Ellipsoid in meters with resolution 0.01 */
+  INT32  AltM;            /* Altitude from Mean Sea Level in meters with resolution 0.01 */
+  UINT8  Datum;           /* Map datum */
+  UINT16 Sog;             /* Speed Over Ground in m/sec with resolution 0.01 */
+  UINT16 Cog;             /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */
+  INT16  MagVar;          /* Magnetic Variation - Reserved */
+  INT16  ClmbRte;         /* Climb rate in m/sec with resolution 0.01 */
+  INT16  HdRte;           /* Heading Rate in deg/sec with resolution 0.01 (SiRFDrive only) */
+  UINT32 Ehpe;            /* Expected Horizontal Position Error in meters with resolution 0.01 */
+  UINT32 Evpe;            /* Expected Horizontal Vertical Error in meters with resolution 0.01 */
+  UINT32 Ete;             /* Expected Time Error in meters with resolution 0.01 (SiRFDrive only) - Reserved */
+  UINT16 Ehve;            /* Expected Horizontal Velocity Error in m/sec with resolution 0.01 (SiRFDrive only) */
+  INT32  ClkBias;         /* Clock Bias in meters with resolution 0.01 */
+  UINT32 ClkBiasE;        /* Clock Bias Error in meters with resolution 0.01 (SiRFDrive only) */
+  INT32  ClkDrift;        /* Clock Drift in m/sec with resolution 0.01 */
+  UINT32 ClkDriftE;       /* Clock Drift in m/sec with resolution 0.01 (SiRFDrive only) */
+  UINT32 Trvled;          /* Distance Traveled since reset in meters (SiRFDrive only) */
+  UINT16 TrvledE;         /* Distance Traveled Error in meters (SiRFDrive only) */
+  UINT16 HdE;             /* Heading Error [0 to 180] in degrees with resolution 0.01 (SiRFDrive only) */
+  UINT8  SVIDCnt;         /* Number of SVs in solution [0 to 12] */
+  UINT8  HDOP;            /* HDOP [0..51] with resolution 0.2 */
+  UINT8  Reserved;        /* Reserved */
+
+  UINT16 ufSog;             /* Speed Over Ground in m/sec with resolution 0.01 ,unfiltered*/
+  UINT16 ufCog;             /* Course Over Ground [0 to 360] in degrees with resolution 0.01, unfiltered  */
+
+}  T_SBN_REC;
+
+#endif
+
+#endif  // NAVILINK_H_INCLUDED_
diff --git a/deprecated/sbn.cc b/deprecated/sbn.cc
new file mode 100644 (file)
index 0000000..222cdd5
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+    Locosys NaviGPS GT-31/BGT-31 SiRF binary logging format (SBN)
+
+    Copyright (C) 2008  Rodney Lorrimar <rodney@rodney.id.au>
+    Copyright (C) 2005  Robert Lipe, robertlipe+source@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <cstring>     // for size_t, memcpy
+
+#include <QDate>       // for QDate
+#include <QDateTime>   // for QDateTime
+#include <QTime>       // for QTime
+#include <QString>     // for QString
+#include <QVector>     // for QVector
+#include <QtGlobal>    // for Q_UNUSED
+#include <Qt>          // for UTC
+
+#include "defs.h"
+#include "gbfile.h"    // for gbfread, gbfclose, gbfeof, gbfopen
+#include "navilink.h"  // for navilink_checksum_packet, locosys_...
+
+
+#define MYNAME "sbn"
+
+static gbfile* file_handle = nullptr;
+
+static
+QVector<arglist_t> sbn_args = {
+};
+
+
+/**********************************************************************/
+
+/* Packets are encoded according to the SiRF Binary Protocol.
+ *
+ *   http://www.navmanwirelessoem.com/oem/customer-support/oem-ne
+ *   ws/product-briefs-and-data-sheets/jupiter-32-xlp-new2/sirf-b
+ *   inary-protocol-reference-manual
+ *
+ * The important packet is "Geodetic Navigation Data" (Message ID 41).
+ */
+
+#define PID_SBN              41
+#define SBN_RECORD_LEN       97 /* 91 plus three two shorts added by Locosys */
+/* V1.3 of the s/w added SDOP and and VSDOP bytes */
+#define PID_VISIBLE_LIST     13
+#define PID_QRY_INFORMATION  253
+#define QRY_INFORMATION_LEN  41
+#define INFO_USERNAME_LEN    13
+#define INFO_SERIAL_NUM_LEN  9
+#define INFO_LOG_RATE_LEN    3
+#define INFO_VERSION_LEN     12
+#define INFO_SEP             ','
+
+
+/*
+ * Very similar to read_packet in navilink.c, except reads from file
+ * instead of serial, and integers are read in big endian order.
+ */
+static size_t
+read_packet(int* type, void* payload, size_t max_len)
+{
+  unsigned char start[4];
+
+  if (gbfread(start, sizeof(start), 1, file_handle) != 1) {
+    if (gbfeof(file_handle)) {
+      return 0;
+    }
+
+    fatal(MYNAME ": Format error: No packet start.\n");
+  }
+
+  if (start[0] != 0xa0 || start[1] != 0xa2) {
+    fatal(MYNAME ": Format error: Bad packet start.\n");
+  }
+
+  size_t size = be_readu16(start + 2);
+
+  if (size < 1 || max_len < size) {
+    fatal(MYNAME ": Format error: unexpected size: %d.\n", (int) size);
+  }
+
+  /* allocate space for checksum and trailing 0xb0b3 */
+  size_t data_size = size + 4;
+
+  /* data_size can be up to about 64k */
+  auto* data = (unsigned char*) xmalloc(data_size);
+
+  if (gbfread(data, data_size, 1, file_handle) != 1) {
+    fatal(MYNAME ": Format error: could not read %d bytes.\n",
+          (int) data_size);
+  }
+
+  *type = data[0];
+
+  unsigned int checksum_exp = be_readu16(data + size);
+  unsigned int checksum_act = navilink_checksum_packet(data, size);
+
+  if (checksum_exp != checksum_act) {
+    fatal(MYNAME ": Checksum error - expected %x got %x\n",
+          checksum_exp, checksum_act);
+  }
+
+  if (data[size + 2] != 0xb0 || data[size + 3] != 0xb3) {
+    fatal(MYNAME ": Format error: Bad packet trailer\n");
+  }
+
+  --size;
+
+  memcpy(payload, data + 1, size);
+  xfree(data);
+
+  return size;
+}
+
+#ifdef LOCOSYS_PARSE_FILE_ID
+static size_t
+hdrcpy(char* dest, const char* src, size_t max_len)
+{
+  size_t i;
+
+  for (i = 0; i < max_len && *src != INFO_SEP; i++) {
+    *dest++ = *src++;
+  }
+  *dest++ = 0;
+
+  return ++i;
+}
+#endif /* LOCOSYS_PARSE_FILE_ID */
+
+bool
+locosys_decode_file_id(char* header, size_t len)
+{
+  Q_UNUSED(header);
+  Q_UNUSED(len);
+#ifdef LOCOSYS_PARSE_FILE_ID
+  /*
+   * MID_FILE_ID(0xfd) contains the following payload :
+   *   User Name, Serial Number, Log Rate, Firmware Version
+   *     >field separator:","
+   *     >User Name : MAX CHAR(13)
+   *     >Serial Number : MAX CHAR(8)
+   *     >Log Rate : MAX CHAR 3, 0..255 in seconds
+   *     >Firmware Version  :  MAX CHAR (13)
+   */
+
+  char username[INFO_USERNAME_LEN + 1];
+  char serial_num[INFO_SERIAL_NUM_LEN + 1];
+  char log_rate[INFO_LOG_RATE_LEN + 1];
+  char version[INFO_VERSION_LEN + 1];
+  char* p = header;
+
+  p += hdrcpy(username,   p, INFO_USERNAME_LEN);
+  p += hdrcpy(serial_num, p, INFO_SERIAL_NUM_LEN);
+  p += hdrcpy(log_rate,   p, INFO_LOG_RATE_LEN);
+  p += hdrcpy(version,    p, INFO_VERSION_LEN);
+
+  printf(MYNAME ": Username: %s\n", username);
+  printf(MYNAME ": Serial Number: %s\n", serial_num);
+  printf(MYNAME ": Log rate (seconds): %s\n", log_rate);
+  printf(MYNAME ": Firmware version: %s\n", version);
+#endif /* LOCOSYS_PARSE_FILE_ID */
+
+  return true;
+}
+
+static void
+read_sbn_header(route_head*)
+{
+  char header[QRY_INFORMATION_LEN];
+  int type = 0;
+
+  size_t len = read_packet(&type, header, sizeof(header));
+
+  if (len == 0 || type != PID_QRY_INFORMATION ||
+      !locosys_decode_file_id(header, len)) {
+    fatal(MYNAME ": Format error: Couldn't read SBN header."
+          "This probably isn't a SBN file.\n");
+  }
+}
+
+static int
+is_sbn_valid(const unsigned char* buffer)
+{
+  /* valid navigation (any bit set implies navigation solution is not
+   * optimal) */
+  return !buffer[0] && !buffer[1];
+}
+
+static fix_type
+decode_sbn_mode(const unsigned char* mode)
+{
+  static const fix_type fixes[8] = {
+    fix_none,     /* 000 No Nav */
+    fix_none,     /* 001 1 SV solution */
+    fix_none,     /* 010 2 SV solution */
+    fix_2d,       /* 011 3 SV solution (2D) */
+    fix_3d,       /* 100 4 or more SV solution (3D) */
+    fix_2d,       /* 101 Least Square 2D solution */
+    fix_3d,       /* 110 Least Square 3D solution */
+    fix_none      /* 111 DR solution (no SV) */
+  };
+  int dgps_correction = *mode & 0x80;
+  fix_type fix = fixes[*mode & 7];
+
+  return dgps_correction && fix == fix_3d ? fix_dgps : fix;
+}
+
+static void
+decode_sbn_datetime(const unsigned char* buffer, Waypoint* waypt)
+{
+  int scaled_seconds = be_readu16(buffer + 6);
+
+  int ms = scaled_seconds % 1000;
+  int sec = scaled_seconds / 1000;
+  int min = buffer[5];
+  int hour = buffer[4];
+  int mday = buffer[3];
+  int mon = buffer[2];
+  int year = be_readu16(buffer);
+
+  waypt->SetCreationTime(QDateTime(QDate(year, mon, mday), QTime(hour, min, sec, ms), Qt::UTC));
+}
+
+static void
+decode_sbn_position(const unsigned char* buffer, Waypoint* waypt)
+{
+  waypt->latitude = be_read32(buffer + 0) * 0.0000001;
+  waypt->longitude = be_read32(buffer + 4) * 0.0000001;
+  waypt->altitude = be_read32(buffer + 12) * 0.01;
+}
+
+static Waypoint*
+decode_sbn_record(unsigned char* buffer)
+{
+  auto* waypt = new Waypoint;
+
+  if (is_sbn_valid(buffer)) {
+    waypt->fix = decode_sbn_mode(buffer + 3);
+  } else {
+    waypt->fix = fix_none;
+  }
+
+  decode_sbn_datetime(buffer + 10, waypt);
+  decode_sbn_position(buffer + 22, waypt);
+  waypt->set_speed(be_read16(buffer + 39) * 0.01f);
+  waypt->set_course(be_read16(buffer + 41) * 0.01f);
+  waypt->sat = buffer[87];
+  waypt->hdop = buffer[88] * 0.2f;
+
+  return waypt;
+}
+
+static void
+add_logpoints(route_head* track)
+{
+  unsigned char buffer[SBN_RECORD_LEN];
+  int type = 0;
+
+  while (read_packet(&type, buffer, sizeof(buffer))) {
+    if (type == PID_SBN) {
+      track_add_wpt(track, decode_sbn_record(buffer));
+    } else if (type == PID_VISIBLE_LIST) {
+      /* A list of visible SVs, their IDs, azimuths, elevations.
+       * Not storing this info for now. */
+    } else {
+      warning(MYNAME ": Format error: Unknown packet type 0x%02x.\n", type);
+    }
+  }
+}
+
+/**********************************************************************/
+
+static void
+sbn_rd_init(const QString& fname)
+{
+  file_handle = gbfopen(fname, "r", MYNAME);
+}
+
+static void
+sbn_rd_deinit()
+{
+  gbfclose(file_handle);
+}
+
+static void
+sbn_read()
+{
+  if (global_opts.masked_objective & TRKDATAMASK) {
+    auto* track = new route_head;
+    track_add_head(track);
+
+    read_sbn_header(track);
+
+    add_logpoints(track);
+  }
+}
+
+/**********************************************************************/
+
+/* Characters are always encoded in ASCII. Even if the unit is set
+ * to Chinese language, only ASCII characters can be entered.
+ */
+
+ff_vecs_t sbn_vecs = {
+  ff_type_file,
+  {
+    ff_cap_none         /* waypoints */,
+    ff_cap_read                                        /* tracks */,
+    ff_cap_none                                        /* routes */
+  },
+  sbn_rd_init,
+  nullptr,
+  sbn_rd_deinit,
+  nullptr,
+  sbn_read,
+  nullptr,
+  nullptr,
+  &sbn_args,
+  NULL_POS_OPS
+};
+/**********************************************************************/
diff --git a/deprecated/sbp.cc b/deprecated/sbp.cc
new file mode 100644 (file)
index 0000000..e990713
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+    Locosys NaviGPS GT-31/BGT-31 binary datalog format (SBP)
+
+    Copyright (C) 2008  Rodney Lorrimar <rodney@rodney.id.au>
+    Copyright (C) 2005  Robert Lipe, robertlipe+source@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ */
+
+#include <cstddef>     // for size_t
+
+#include <QString>     // for QString
+#include <QVector>     // for QVector
+
+#include "defs.h"
+#include "gbfile.h"    // for gbfread, gbfclose, gbfopen, gbfile
+#include "navilink.h"  // for locosys_decode_file_id, navilink_decode_logpoint
+
+
+#define MYNAME "sbp"
+
+static gbfile* file_handle = nullptr;
+
+static
+QVector<arglist_t> sbp_args = {
+};
+
+/*******************************************************************************
+* %%%        global callbacks called by gpsbabel main process              %%% *
+*******************************************************************************/
+
+static void
+sbp_rd_init(const QString& fname)
+{
+  file_handle = gbfopen(fname, "r", MYNAME);
+}
+
+static void
+sbp_rd_deinit()
+{
+  gbfclose(file_handle);
+}
+
+static void
+read_sbp_header(route_head*)
+{
+  /*
+   * A complete SBP file contains 64 bytes header,
+   *
+   * Here is the definition of the SBP header
+   * BYTE 0 ~1 : true SBP header length
+   * BYTE 2~63:  MID_FILE_ID(0xfd)
+   *             will stuff 0xff for remaining bytes
+   */
+
+#define HEADER_SKIP 7
+
+  bool success;
+  char header[64];
+
+  if (gbfread(header, sizeof(header), 1, file_handle) == 1) {
+    size_t len = le_read16(header) - HEADER_SKIP;
+    if (len > sizeof(header)) {
+      len = sizeof(header);
+    }
+
+    success = locosys_decode_file_id(header + HEADER_SKIP, len);
+  } else {
+    success = false;
+  }
+
+  if (!success) {
+    fatal(MYNAME ": Format error: Couldn't read SBP header."
+          "This probably isn't a SBP file.\n");
+  }
+}
+
+static Waypoint*
+read_logpoint()
+{
+  unsigned char buffer[SBP_RECORD_LEN];
+
+  if (gbfread(buffer, sizeof(buffer), 1, file_handle) == 1) {
+    return navilink_decode_logpoint(buffer);
+  }
+
+  return nullptr;
+}
+
+static void
+sbp_read()
+{
+  Waypoint* logpoint;
+
+  auto* track = new route_head;
+  track_add_head(track);
+
+  read_sbp_header(track);
+
+  while ((logpoint = read_logpoint())) {
+    track_add_wpt(track, logpoint);
+  }
+}
+
+/**************************************************************************/
+
+/* ascii is the expected character set */
+/* not fixed, can be changed through command line parameter */
+
+ff_vecs_t sbp_vecs = {
+  ff_type_file,
+  {
+    ff_cap_none         /* waypoints */,
+    ff_cap_read                                        /* tracks */,
+    ff_cap_none                                        /* routes */
+  },
+  sbp_rd_init,
+  nullptr,
+  sbp_rd_deinit,
+  nullptr,
+  sbp_read,
+  nullptr,
+  nullptr,
+  &sbp_args,
+  NULL_POS_OPS
+};
+/**************************************************************************/
diff --git a/navilink.cc b/navilink.cc
deleted file mode 100644 (file)
index c97ed13..0000000
+++ /dev/null
@@ -1,1220 +0,0 @@
-/*
-    NaviGPS serial protocol.
-
-    Copyright (C) 2007 Tom Hughes, tom@compton.nu
-    Copyright (C) 2008 Rodney Lorrimar, rodney@rodney.id.au
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
- */
-
-
-/* Based on description at http://wiki.splitbrain.org/navilink */
-
-#include <cstdio>                  // for fprintf, stderr
-#include <cstring>                 // for memcpy, memset, strncpy
-
-#include <QByteArray>              // for QByteArray
-#include <QDate>                   // for QDate
-#include <QDateTime>               // for QDateTime
-#include <QString>                 // for QString, operator==
-#include <QThread>                 // for QThread
-#include <QTime>                   // for QTime
-#include <QVector>                 // for QVector
-#include <QtCore>                  // for qRound, qPrintable, UTC
-
-#include "defs.h"
-#include "navilink.h"
-#include "gbfile.h"                // for gbfwrite, gbfclose, gbfopen, gbfread
-#include "gbser.h"                 // for gbser_read_wait, gbser_deinit, gbs...
-#include "jeeps/gpsmath.h"         // for GPS_Math_WGS84_To_UTM_EN
-#include "jeeps/gpsport.h"         // for int32
-#include "src/core/datetime.h"     // for DateTime
-
-
-#define MYNAME "NAVILINK"
-
-static char* nuketrk = nullptr;
-static char* nukerte = nullptr;
-static char* nukewpt = nullptr;
-static char* nukedlg = nullptr;
-static char* poweroff = nullptr;
-static char* datalog = nullptr;
-
-static void* serial_handle = nullptr;
-static gbfile* file_handle = nullptr;
-
-static unsigned char* track_data;
-static unsigned char* track_data_ptr;
-static unsigned char* track_data_end;
-static unsigned track_serial;
-static Waypoint** route_waypts;
-static unsigned* route_ids;
-static unsigned route_id_ptr;
-
-static enum {
-  READING,
-  WRITING
-} operation = READING;
-
-#define SERIAL_TIMEOUT        8000
-#define CLEAR_DATALOG_TIME    7000
-
-#define MAX_WAYPOINTS         1000
-#define MAX_SUBROUTES         9
-#define MAX_SUBROUTE_LENGTH   14
-#define MAX_ROUTE_LENGTH      (MAX_SUBROUTES * MAX_SUBROUTE_LENGTH - 1)
-#define MAX_READ_TRACKPOINTS  512
-#define MAX_WRITE_TRACKPOINTS 127
-#define MAX_READ_LOGPOINTS    256
-
-#define PID_SYNC              0xd6
-#define PID_ACK               0x0c
-#define PID_NAK               0x00
-#define PID_QRY_INFORMATION   0x20
-#define PID_QRY_FW_VERSION    0xfe
-#define PID_DATA              0x03
-#define PID_ADD_A_WAYPOINT    0x3c
-#define PID_QRY_WAYPOINTS     0x28
-#define PID_QRY_ROUTE         0x24
-#define PID_DEL_WAYPOINT      0x36
-#define PID_DEL_ALL_WAYPOINT  0x37
-#define PID_DEL_ROUTE         0x34
-#define PID_DEL_ALL_ROUTE     0x35
-#define PID_ADD_A_ROUTE       0x3d
-#define PID_ERASE_TRACK       0x11
-#define PID_READ_TRACKPOINTS  0x14
-#define PID_WRITE_TRACKPOINTS 0x16
-#define PID_CMD_OK            0xf3
-#define PID_CMD_FAIL          0xf4
-#define PID_QUIT              0xf2
-#define PID_INFO_DATALOG      0x1c
-#define PID_READ_DATALOG      0x14
-#define PID_CLEAR_DATALOG     0x1b
-
-static
-const char* const icon_table[] = {
-  "Star",
-  "Flag",
-  "House",
-  "Left Sign",
-  "Telegraph Pole",
-  "People",
-  "Fuel",
-  "Phone",
-  "Pole",
-  "Mountain",
-  "Water",
-  "Tree",
-  "Road Narrows",
-  "Crossroads",
-  "Road Fork",
-  "Turn Right",
-  "Turn Left",
-  "Bird",
-  "3D House",
-  "Trig Point",
-  "Tower",
-  "Cable Car",
-  "Church",
-  "Telegraph Pole",
-  "Skier",
-  "Anchor",
-  "Fish",
-  "Fishes",
-  "Rain",
-  "Fisherman",
-  "Tower",
-  "Boats",
-  "Boat",
-  "Bicycle",
-  "Railway Track",
-  "Dollar Sign",
-  "Bus",
-  "Camera",
-  "Fuel Pump",
-  "Cup",
-  "Merging Road",
-  "Plane",
-  "Red Cross",
-  "House",
-  "Parking"
-};
-
-static
-QVector<arglist_t> navilink_args = {
-  {
-    "nuketrk", &nuketrk, "Delete all track points", nullptr, ARGTYPE_BOOL,
-    ARG_NOMINMAX, nullptr
-  },
-  {
-    "nukerte", &nukerte, "Delete all routes", nullptr, ARGTYPE_BOOL,
-    ARG_NOMINMAX, nullptr
-  },
-  {
-    "nukewpt", &nukewpt, "Delete all waypoints", nullptr, ARGTYPE_BOOL,
-    ARG_NOMINMAX, nullptr
-  },
-  {
-    "nukedlg", &nukedlg, "Clear the datalog", nullptr, ARGTYPE_BOOL,
-    ARG_NOMINMAX, nullptr
-  },
-  {
-    "datalog", &datalog, "Read from datalogger buffer",
-    nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
-  },
-  {
-    "power_off", &poweroff, "Command unit to power itself down",
-    nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
-  },
-};
-
-static void (*write_waypoint)(const Waypoint*) = nullptr;
-static void (*write_track_start)(const route_head* track) = nullptr;
-static void (*write_track_point)(const Waypoint* waypt) = nullptr;
-static void (*write_track_end)(const route_head* track) = nullptr;
-static void (*write_route_start)(const route_head* track) = nullptr;
-static void (*write_route_point)(const Waypoint* waypt) = nullptr;
-static void (*write_route_end)(const route_head* track) = nullptr;
-
-static int
-find_icon_from_descr(const QString& descr)
-{
-  for (unsigned int i = 0; i < sizeof(icon_table) / sizeof(const char*); i++) {
-    if (0 == descr.compare(icon_table[i])) {
-      return i;
-    }
-  }
-
-  return 0;
-}
-
-static void
-free_waypoints(Waypoint** waypts)
-{
-  for (Waypoint** wayptp = waypts; wayptp < waypts + MAX_WAYPOINTS; wayptp++) {
-    if (*wayptp) {
-      delete *wayptp;
-    }
-  }
-
-  xfree(waypts);
-}
-
-static unsigned
-compare_waypoints(const Waypoint* waypt1, const Waypoint* waypt2)
-{
-  return waypt1->latitude == waypt2->latitude &&
-         waypt1->longitude == waypt2->longitude &&
-         waypt1->altitude == waypt2->altitude &&
-         waypt1->shortname == waypt2->shortname;
-}
-
-unsigned
-navilink_checksum_packet(const unsigned char* packet, unsigned length)
-{
-  unsigned checksum = 0;
-
-  while (length-- > 0) {
-    checksum += *packet++;
-  }
-
-  return checksum & 0x7fff;
-}
-
-static void
-dump_packet(const char* prefix, unsigned char* packet, unsigned length)
-{
-  unsigned i;
-
-  for (i = 0; i < length; i++) {
-    if ((i % 16) == 0) {
-      fprintf(stderr, "%s %08x :", prefix, i);
-    }
-    fprintf(stderr, " %02x", packet[i]);
-    if ((i % 16) == 15 || i == length - 1) {
-      fprintf(stderr, "\n");
-    }
-  }
-
-  fprintf(stderr, "\n");
-}
-
-static void
-write_packet(unsigned type, const void* payload, unsigned length)
-{
-  auto* packet = (unsigned char*) xmalloc(length + 9);
-
-  packet[0] = 0xa0;
-  packet[1] = 0xa2;
-  le_write16(packet + 2, length + 1);
-  packet[4] = type;
-  if (length > 0) {
-    memcpy(packet + 5, payload, length);
-  }
-  le_write16(packet + length + 5, navilink_checksum_packet(packet + 4, length + 1));
-  packet[length + 7] = 0xb0;
-  packet[length + 8] = 0xb3;
-
-  if (global_opts.debug_level >= 2) {
-    dump_packet(">>>", packet + 4, length + 1);
-  }
-
-  if (gbser_write(serial_handle, packet, length + 9) != gbser_OK) {
-    fatal(MYNAME ": Write error\n");
-  }
-
-  xfree(packet);
-}
-
-static unsigned
-read_word()
-{
-  unsigned char buffer[2];
-
-  if (gbser_read_wait(serial_handle, buffer, 2, SERIAL_TIMEOUT) != 2) {
-    fatal(MYNAME ": Read error\n");
-  }
-
-  return (buffer[1] << 8) | buffer[0];
-}
-
-/*
- * Read a protocol packet into payload.
- *
- * handle_nak determines behaviour when a PID_NAK packet is read from
- * the device:
- *  - if handle_nak is false, a fatal error will be raised.
- *  - if handle_nak is true, read_packet will simply return false.
- *
- * Returns true if the packet was successfully read into payload.
- */
-static bool
-read_packet(unsigned type, void* payload,
-            int minlength, int maxlength,
-            bool handle_nak)
-{
-  if (read_word() != 0xa2a0) {
-    fatal(MYNAME ": Protocol error: Bad packet header."
-          " Is your NaviGPS in NAVILINK mode?\n");
-  }
-
-  int size;
-  if ((size = read_word()) <= minlength) {
-    fatal(MYNAME ": Protocol error: Packet too short\n");
-  }
-
-  auto* data = (unsigned char*) xmalloc(size);
-
-  if (gbser_read_wait(serial_handle, data, size, SERIAL_TIMEOUT) != size) {
-    fatal(MYNAME ": Read error reading %d byte payload\n", size);
-  }
-
-  if (global_opts.debug_level >= 2) {
-    dump_packet("<<<", data, size);
-  }
-
-  if (data[0] != type) {
-    if (handle_nak && data[0] == PID_NAK) {
-      return false;
-    }
-
-    fatal(MYNAME ": Protocol error: Bad packet type (expected 0x%02x but got 0x%02x)\n", type, data[0]);
-  }
-
-  unsigned checksum;
-  if ((checksum = read_word()) != navilink_checksum_packet(data, size)) {
-    fatal(MYNAME ": Checksum error - expected %x got %x\n",
-          navilink_checksum_packet(data, size), checksum);
-  }
-
-  if (read_word() != 0xb3b0) {
-    fatal(MYNAME ": Protocol error: Bad packet trailer\n");
-  }
-
-  if (size - 1 > maxlength) {
-    memcpy(payload, data + 1, maxlength);
-  } else {
-    memcpy(payload, data + 1, size - 1);
-  }
-
-  xfree(data);
-
-  return true;
-}
-
-static QDateTime
-decode_datetime(const unsigned char* buffer)
-{
-  QTime tm(buffer[3], buffer[4], buffer[5]);
-  QDate dt(2000 + buffer[0], buffer[1], buffer[2]);
-  return QDateTime(dt, tm, Qt::UTC);
-}
-
-static void
-encode_datetime(const QDateTime& datetime, unsigned char* buffer)
-{
-  if (datetime.isValid()) {
-    QDateTime dt = datetime.toUTC();
-    QDate date = dt.date();
-    QTime time = dt.time();
-    buffer[0] = date.year() - 2000;
-    buffer[1] = date.month();
-    buffer[2] = date.day();
-    buffer[3] = time.hour();
-    buffer[4] = time.minute();
-    buffer[5] = time.second();
-  } else {
-    memset(buffer, 0, 6);
-  }
-}
-
-static void
-decode_position(const unsigned char* buffer, Waypoint* waypt)
-{
-  waypt->latitude = le_read32(buffer + 0) / 10000000.0;
-  waypt->longitude = le_read32(buffer + 4) / 10000000.0;
-  waypt->altitude = FEET_TO_METERS(le_read16(buffer + 8));
-}
-
-static void
-encode_position(const Waypoint* waypt, unsigned char* buffer)
-{
-  le_write32(buffer + 0, qRound(waypt->latitude * 10000000));
-  le_write32(buffer + 4, qRound(waypt->longitude * 10000000));
-  le_write16(buffer + 8, qRound(METERS_TO_FEET(waypt->altitude)));
-}
-
-static unsigned
-decode_waypoint_id(const unsigned char* buffer)
-{
-  unsigned id = le_read16(buffer + 2);
-
-  if (id >= MAX_WAYPOINTS) {
-    fatal(MYNAME ": Invalid waypoint ID\n");
-  }
-
-  return id;
-}
-
-static Waypoint*
-decode_waypoint(const unsigned char* buffer)
-{
-  auto* waypt = new Waypoint;
-
-  decode_position(buffer + 12, waypt);
-  waypt->shortname = reinterpret_cast<const char*>(buffer) + 4;
-  waypt->icon_descr = icon_table[buffer[28]];
-  waypt->SetCreationTime(decode_datetime(buffer + 22));
-
-  return waypt;
-}
-
-static void
-encode_waypoint(const Waypoint* waypt, unsigned char* buffer)
-{
-  buffer[0] = 0x00;
-  buffer[1] = 0x40;
-  le_write16(buffer + 2, 0);
-  strncpy((char*)buffer + 4, CSTRc(waypt->shortname), 6);
-  buffer[10] = 0;
-  buffer[11] = 0;
-  encode_position(waypt, buffer + 12);
-  encode_datetime(waypt->GetCreationTime(), buffer + 22);
-  buffer[28] = find_icon_from_descr(waypt->icon_descr);
-  buffer[29] = 0;
-  buffer[30] = 0x00;
-  buffer[31] = 0x7e;
-}
-
-static Waypoint*
-decode_trackpoint(const unsigned char* buffer)
-{
-  auto* waypt = new Waypoint;
-
-  decode_position(buffer + 12, waypt);
-  waypt->SetCreationTime(decode_datetime(buffer + 22));
-  waypt->set_course(le_read16(buffer + 2));
-  waypt->set_speed(KPH_TO_MPS(buffer[29] * 2));
-
-  return waypt;
-}
-
-static void
-encode_trackpoint(const Waypoint* waypt, unsigned serial, unsigned char* buffer)
-{
-  double x;
-  double y;
-  int32  z;
-  char   zc;
-
-  GPS_Math_WGS84_To_UTM_EN(waypt->latitude, waypt->longitude, &x, &y, &z, &zc);
-
-  le_write16(buffer + 0, serial);
-  le_write16(buffer + 2, qRound(waypt->course_value_or(0)));
-  le_write32(buffer + 4, qRound(x));
-  le_write32(buffer + 8, qRound(y));
-  encode_position(waypt, buffer + 12);
-  encode_datetime(waypt->GetCreationTime(), buffer + 22);
-  buffer[28] = z;
-  buffer[29] = qRound(MPS_TO_KPH(waypt->speed_value_or(0) / 2));
-  buffer[30] = 0x5a;
-  buffer[31] = 0x7e;
-}
-
-static Waypoint**
-serial_read_waypoints()
-{
-  Waypoint**       waypts = nullptr;
-  unsigned char  information[32];
-
-  if (global_opts.masked_objective & RTEDATAMASK) {
-    waypts = (Waypoint**) xcalloc(MAX_WAYPOINTS, sizeof(Waypoint*));
-  }
-
-  write_packet(PID_QRY_INFORMATION, nullptr, 0);
-  read_packet(PID_DATA, information,
-              sizeof(information), sizeof(information),
-              false);
-
-  unsigned short total = le_read16(information + 0);
-
-  for (unsigned short start = 0; start < total; start += 32) {
-    unsigned short count = total - start;
-    unsigned char  payload[7];
-
-    if (count > 32) {
-      count = 32;
-    }
-
-    le_write32(payload + 0, start);
-    le_write16(payload + 4, count);
-    payload[6] = 1;
-
-    write_packet(PID_QRY_WAYPOINTS, payload, sizeof(payload));
-
-    auto*  waypoints = (unsigned char*) xmalloc(count * 32);
-
-    read_packet(PID_DATA, waypoints, count * 32, count * 32, false);
-
-    for (unsigned char*  w = waypoints; w < waypoints + count * 32; w = w + 32) {
-      if (global_opts.masked_objective & WPTDATAMASK) {
-        waypt_add(decode_waypoint(w));
-      }
-      if (global_opts.masked_objective & RTEDATAMASK) {
-        waypts[decode_waypoint_id(w)] = decode_waypoint(w);
-      }
-    }
-
-    xfree(waypoints);
-
-    if (global_opts.verbose_status) {
-      waypt_status_disp(total, start + count);
-    }
-  }
-
-  return waypts;
-}
-
-static unsigned int
-serial_write_waypoint_packet(const Waypoint* waypt)
-{
-  unsigned char data[32];
-  unsigned char id[2];
-
-  encode_waypoint(waypt, data);
-  write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data));
-  if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), true)) {
-    fatal(MYNAME ": Could not write waypoint.\n");
-  }
-
-  return le_read16(id);
-}
-
-static void
-serial_write_waypoint(const Waypoint* waypt)
-{
-  serial_write_waypoint_packet(waypt);
-}
-
-static void
-serial_read_track()
-{
-  unsigned char  information[32];
-
-  write_packet(PID_QRY_INFORMATION, nullptr, 0);
-  read_packet(PID_DATA, information,
-              sizeof(information), sizeof(information),
-              false);
-
-  unsigned int address = le_read32(information + 4);
-  unsigned short total = le_read16(information + 12);
-
-  auto* track = new route_head;
-  track_add_head(track);
-
-  while (total > 0) {
-    unsigned short count = total < MAX_READ_TRACKPOINTS ? total : MAX_READ_TRACKPOINTS;
-    unsigned char  payload[7];
-
-    le_write32(payload + 0, address);
-    le_write16(payload + 4, count * 32);
-    payload[6] = 0x00;
-
-    write_packet(PID_READ_TRACKPOINTS, payload, sizeof(payload));
-
-    auto*  trackpoints = (unsigned char*) xmalloc(count * 32);
-
-    read_packet(PID_DATA, trackpoints, count * 32, count * 32, false);
-    write_packet(PID_ACK, nullptr, 0);
-
-    for (unsigned char*  t = trackpoints; t < trackpoints + count * 32; t = t + 32) {
-      track_add_wpt(track, decode_trackpoint(t));
-    }
-
-    xfree(trackpoints);
-
-    address = address + count * 32;
-    total = total - count;
-  }
-}
-
-static void
-serial_write_track()
-{
-  unsigned char  information[32];
-  unsigned char  data[7];
-
-  write_packet(PID_QRY_INFORMATION, nullptr, 0);
-  read_packet(PID_DATA, information,
-              sizeof(information), sizeof(information),
-              false);
-
-  unsigned int address = le_read32(information + 4);
-  unsigned short total = le_read16(information + 12);
-
-  le_write32(data + 0, address + total * 32);
-  le_write16(data + 4, track_data_ptr - track_data);
-  data[6] = 0x00;
-
-  write_packet(PID_WRITE_TRACKPOINTS, data, sizeof(data));
-  QThread::usleep(10000);
-  write_packet(PID_DATA, track_data, track_data_ptr - track_data);
-  read_packet(PID_CMD_OK, nullptr, 0, 0, false);
-
-  track_data_ptr = track_data;
-}
-
-static void
-serial_write_track_start(const route_head*)
-{
-  track_data = (unsigned char*) xmalloc(MAX_WRITE_TRACKPOINTS * 32);
-  track_data_ptr = track_data;
-  track_data_end = track_data + MAX_WRITE_TRACKPOINTS * 32;
-}
-
-static void
-serial_write_track_point(const Waypoint* waypt)
-{
-  if (track_data_ptr >= track_data_end) {
-    serial_write_track();
-  }
-
-  encode_trackpoint(waypt, 0, track_data_ptr);
-
-  track_data_ptr += 32;
-}
-
-static void
-serial_write_track_end(const route_head*)
-{
-  if (track_data_ptr > track_data) {
-    serial_write_track();
-  }
-
-  xfree(track_data);
-}
-
-static void
-serial_read_routes(Waypoint** waypts)
-{
-  unsigned char information[32];
-
-  write_packet(PID_QRY_INFORMATION, nullptr, 0);
-  read_packet(PID_DATA, information,
-              sizeof(information), sizeof(information),
-              false);
-
-  unsigned char routec = information[2];
-
-  for (unsigned char r = 0; r < routec; r++) {
-    unsigned char payload[7];
-    unsigned char routedata[320];
-
-    le_write32(payload + 0, r);
-    le_write16(payload + 2, 0);
-    payload[6] = 0x01;
-
-    write_packet(PID_QRY_ROUTE, payload, sizeof(payload));
-    read_packet(PID_DATA, routedata, 64, sizeof(routedata), false);
-
-    auto* route = new route_head;
-    route->rte_num = routedata[2];
-    route->rte_name = (char*)routedata + 4;
-    route_add_head(route);
-
-    for (int sr = 0; sr < MAX_SUBROUTES; sr++) {
-      for (int w = 0; w < MAX_SUBROUTE_LENGTH; w++) {
-        unsigned short id = le_read16(routedata + 34 + 32 * sr + 2 *w);
-
-        if (id == 0xffffu) {
-          w = MAX_SUBROUTE_LENGTH;
-          sr = MAX_SUBROUTES;
-        } else if (id >= MAX_WAYPOINTS) {
-          fatal(MYNAME ": Invalid waypoint ID in route\n");
-        } else if (waypts[id] == nullptr) {
-          fatal(MYNAME ": Non-existent waypoint in route\n");
-        } else {
-          route_add_wpt(route, new Waypoint(*waypts[id]));
-        }
-      }
-    }
-  }
-}
-
-static void
-serial_write_route_start(const route_head* route)
-{
-  route_ids = (unsigned int*) xmalloc(route->rte_waypt_ct() * sizeof(unsigned));
-  route_id_ptr = 0;
-}
-
-static void
-serial_write_route_point(const Waypoint* waypt)
-{
-  unsigned w;
-
-  for (w = 0; w < MAX_WAYPOINTS; w++) {
-    if (route_waypts[w] && compare_waypoints(waypt, route_waypts[w])) {
-      break;
-    }
-  }
-
-  if (w == MAX_WAYPOINTS) {
-    w = serial_write_waypoint_packet(waypt);
-    route_waypts[w] = new Waypoint(*waypt);
-  }
-
-  route_ids[route_id_ptr++] = w;
-}
-
-static void
-serial_write_route_end(const route_head* route)
-{
-  unsigned char id[1];
-
-  QString rte_name = route->rte_name;
-  if (rte_name == nullptr) {
-    rte_name = "NO NAME";
-  }
-  if (route_id_ptr > MAX_ROUTE_LENGTH) {
-    fatal(MYNAME ": Route %s too long\n", qPrintable(route->rte_name));
-  }
-
-  unsigned src = (route_id_ptr + MAX_SUBROUTE_LENGTH) / MAX_SUBROUTE_LENGTH;
-  auto* data = (unsigned char*) xmalloc(32 + src * 32);
-
-  le_write16(data + 0, 0x2000);
-  data[2] = 0;
-  data[3] = 0x20;
-  memset(data + 4, 0, 14);
-  strncpy((char*)data + 4, CSTR(rte_name), 13);
-  data[18] = 0;
-  data[19] = 0;
-  le_write32(data + 20, 0);
-  le_write32(data + 24, 0);
-  le_write16(data + 28, 0);
-  data[30] = 0x7b;
-  data[31] = 0x77;
-
-  for (unsigned sr = 0; sr < src; sr++) {
-    unsigned char* srdata = data + 32 + 32 * sr;
-    unsigned      pt_offset = MAX_SUBROUTE_LENGTH * sr;
-
-    le_write16(srdata + 0, 0x2010);
-
-    for (unsigned pt = 0; pt < MAX_SUBROUTE_LENGTH; pt++) {
-      if (pt_offset + pt < route_id_ptr) {
-        le_write16(srdata + 2 + 2 * pt, route_ids[pt_offset + pt]);
-      } else {
-        le_write16(srdata + 2 + 2 * pt, 0xffffu);
-      }
-    }
-
-    srdata[30] = 0x7f;
-    srdata[31] = 0x77;
-  }
-
-  write_packet(PID_ADD_A_ROUTE, data, 32 + src * 32);
-  if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), true)) {
-    fatal(MYNAME ": Could not add route.\n");
-  }
-
-  xfree(data);
-  xfree(route_ids);
-}
-
-static int
-decode_sbp_msec(const unsigned char* buffer)
-{
-  int msec = le_read16(buffer);
-  return (msec % 1000);
-}
-
-static QDateTime
-decode_sbp_datetime_packed(const unsigned char* buffer)
-{
-  /*
-   * Packed_Date_Time_UTC:
-   *   bit 31..22 :year*12+month (10 bits) :   real year= year+2000
-   *   bit17.21: day (5bits)
-   *   bit12.16: hour (5bits)
-   *   bit6..11: min  (6bits)
-   *   bit0..5 : sec  (6bits)
-   *
-   * 0        1        2        3
-   * 01234567 01234567 01234567 01234567
-   * ........ ........ ........ ........
-   * SSSSSSMM MMMMHHHH Hdddddmm mmmmmmmm
-   */
-
-  int sec = buffer[0] & 0x3F;
-  int min = ((buffer[0] & 0xC0) >> 6) | ((buffer[1] & 0x0F) << 2);
-  int hour = ((buffer[1] & 0xF0) >> 4) | ((buffer[2] & 0x01) << 4);
-  int mday = (buffer[2] & 0x3E) >> 1;
-  int months = ((buffer[2] & 0xC0) >> 6) | buffer[3] << 2;
-  int mon = months % 12;
-  int year = 2000 + months / 12;
-
-  return {QDate(year, mon, mday), QTime(hour, min, sec), Qt::UTC};
-}
-
-static void
-decode_sbp_position(const unsigned char* buffer, Waypoint* waypt)
-{
-  waypt->latitude = le_read32(buffer + 0) / 10000000.0;
-  waypt->longitude = le_read32(buffer + 4) / 10000000.0;
-  waypt->altitude = le_read32(buffer + 8) / 100.0;
-}
-
-Waypoint*
-navilink_decode_logpoint(const unsigned char* buffer)
-{
-  auto* waypt = new Waypoint;
-
-  waypt->hdop = (buffer[0]) * 0.2f;
-  waypt->sat = buffer[1];
-  waypt->SetCreationTime(decode_sbp_datetime_packed(buffer + 4)
-                         .addMSecs(decode_sbp_msec(buffer + 2)));
-  decode_sbp_position(buffer + 12, waypt);
-  waypt->set_speed(le_read16(buffer + 24) * 0.01f);
-  waypt->set_course(le_read16(buffer + 26) * 0.01f);
-
-  return waypt;
-}
-
-/*
- * The datalog is a circular buffer, so it may be necessary to glue
- * together two segments. This function queries the device for the
- * circular buffer pointers, and returns two pairs of address/length.
- * If there is only one segment (i.e. the datalog has not yet wrapped
- * around), then seg2_addr and seg2_len will be zero.
- */
-static void
-read_datalog_info(unsigned int* seg1_addr, unsigned int* seg1_len,
-                  unsigned int* seg2_addr, unsigned int* seg2_len)
-{
-  unsigned char  info[16];
-
-  write_packet(PID_INFO_DATALOG, nullptr, 0);
-  read_packet(PID_DATA, info, sizeof(info), sizeof(info), false);
-
-  unsigned int flash_start_addr = le_read32(info);
-  unsigned int flash_length = le_read32(info + 4);
-  unsigned int data_start_addr = le_read32(info + 8);
-  unsigned int next_blank_addr = le_read32(info + 12);
-
-  if (data_start_addr > next_blank_addr) {
-    /* usually there are two segments to be read */
-    *seg1_addr = data_start_addr;
-    *seg1_len = flash_start_addr + flash_length - *seg1_addr;
-    *seg2_addr = flash_start_addr;
-    *seg2_len = next_blank_addr - flash_start_addr;
-  } else {
-    /* hasn't wrapped around yet, only one segment */
-    *seg1_addr = data_start_addr;
-    *seg1_len = next_blank_addr - data_start_addr;
-    *seg2_addr = 0;
-    *seg2_len = 0;
-  }
-
-  if (*seg1_len & 0x1F || *seg2_len & 0x1F) {
-    fatal(MYNAME ": Protocol error: datalog lengths %u, %u "
-          "not aligned to 32 bytes\n", *seg1_len, *seg2_len);
-  }
-}
-
-static void
-read_datalog_records(route_head* track,
-                     unsigned int start_addr, unsigned int len)
-{
-  unsigned char  payload[7];
-
-  /* The protocol only supports reading 256 logpoints at once, so
-   * read small chunks until none left. */
-  while (len > 0) {
-    unsigned char  logpoints[MAX_READ_LOGPOINTS * SBP_RECORD_LEN];
-    unsigned int   logpoints_len = len > MAX_READ_LOGPOINTS ? MAX_READ_LOGPOINTS : len;
-
-    le_write32(payload, start_addr);
-    le_write16(payload + 4, logpoints_len);
-    payload[6] = 0x01;
-
-    write_packet(PID_READ_DATALOG, payload, sizeof(payload));
-    read_packet(PID_DATA, logpoints, logpoints_len, logpoints_len, false);
-    write_packet(PID_ACK, nullptr, 0);
-
-    for (unsigned char* p = logpoints; p < logpoints + logpoints_len; p += 32) {
-      track_add_wpt(track, navilink_decode_logpoint(p));
-    }
-
-    len -= logpoints_len;
-    start_addr += logpoints_len;
-  }
-}
-
-static void
-serial_read_datalog()
-{
-  unsigned int seg1_addr;
-  unsigned int seg1_len;
-  unsigned int seg2_addr;
-  unsigned int seg2_len;
-
-  read_datalog_info(&seg1_addr, &seg1_len, &seg2_addr, &seg2_len);
-
-  auto* track = new route_head;
-  track_add_head(track);
-
-  if (seg1_len) {
-    read_datalog_records(track, seg1_addr, seg1_len);
-  }
-
-  if (seg2_len) {
-    read_datalog_records(track, seg2_addr, seg2_len);
-  }
-}
-
-static void
-file_read()
-{
-  unsigned char data[32];
-  route_head*    track = nullptr;
-
-  while (gbfread(data, sizeof(data), 1, file_handle) == 1) {
-    switch (le_read16(data)) {
-    case 0x2000:
-      fatal(MYNAME ": Route objects not supported in file sources\n");
-      break;
-    case 0x2010:
-      fatal(MYNAME ": Subroute objects not supported in file sources\n");
-      break;
-    case 0x4000:
-      if (global_opts.masked_objective & WPTDATAMASK) {
-        waypt_add(decode_waypoint(data));
-      }
-      break;
-    default:
-      if (global_opts.masked_objective & TRKDATAMASK) {
-        if (track == nullptr) {
-          track = new route_head;
-          track_add_head(track);
-        }
-
-        track_add_wpt(track, decode_trackpoint(data));
-      }
-      break;
-    }
-  }
-}
-
-static void
-file_write_waypoint(const Waypoint* waypt)
-{
-  unsigned char data[32];
-
-  encode_waypoint(waypt, data);
-  gbfwrite(data, sizeof(data), 1, file_handle);
-}
-
-static void
-file_write_track_start(const route_head*)
-{
-  track_serial = 1;
-}
-
-static void
-file_write_track_point(const Waypoint* waypt)
-{
-  unsigned char data[32];
-
-  encode_trackpoint(waypt, track_serial++, data);
-  gbfwrite(data, sizeof(data), 1, file_handle);
-}
-
-static void
-file_write_track_end(const route_head*)
-{
-}
-
-static void
-file_write_route_start(const route_head*)
-{
-  fatal(MYNAME ": Can't write routes to a file\n");
-}
-
-static void
-file_write_route_point(const Waypoint*)
-{
-}
-
-static void
-file_write_route_end(const route_head*)
-{
-}
-
-static void
-nuke()
-{
-  if (nuketrk) {
-    unsigned char information[32];
-    unsigned char data[7];
-
-    write_packet(PID_QRY_INFORMATION, nullptr, 0);
-    read_packet(PID_DATA, information,
-                sizeof(information), sizeof(information),
-                false);
-
-    le_write32(data + 0, le_read32(information + 4));
-    le_write16(data + 4, 0);
-    data[6] = 0;
-
-    write_packet(PID_ERASE_TRACK, data, sizeof(data));
-    read_packet(PID_CMD_OK, nullptr, 0, 0, false);
-  }
-
-  if (nukerte) {
-    unsigned char data[4];
-
-    le_write32(data, 0x00f00000);
-    write_packet(PID_DEL_ALL_ROUTE, data, sizeof(data));
-    if (!read_packet(PID_ACK, nullptr, 0, 0, true)) {
-      fatal(MYNAME ": Could not nuke all routes.\n");
-    }
-  }
-
-  if (nukewpt) {
-    unsigned char data[4];
-
-    le_write32(data, 0x00f00000);
-    write_packet(PID_DEL_ALL_WAYPOINT, data, sizeof(data));
-    if (!read_packet(PID_ACK, nullptr, 0, 0, true)) {
-      fatal(MYNAME ": You must nuke all routes before nuking waypoints.\n");
-      /* perhaps a better action would be to nuke routes for user.
-       * i.e. set nukerte when nukewpt is set */
-    }
-  }
-
-  if (nukedlg) {
-    write_packet(PID_CLEAR_DATALOG, nullptr, 0);
-    /* The flash erase operation is time-consuming. Each sector (64KB)
-     * takes around 1 second.  The total sectors for SBP is 10.
-     * So give the device some time to clear its datalog, in addition
-     * to SERIAL_TIMEOUT, which applies to read_packet() */
-    QThread::usleep(CLEAR_DATALOG_TIME * 1000);
-    read_packet(PID_ACK, nullptr, 0, 0, false);
-  }
-}
-
-static void
-navilink_common_init(const QString& name)
-{
-  if (gbser_is_serial(qPrintable(name))) {
-    if ((serial_handle = gbser_init(qPrintable(name))) == nullptr) {
-      fatal(MYNAME ": Could not open serial port %s\n", qPrintable(name));
-    }
-
-    if (gbser_set_port(serial_handle, 115200, 8, 0, 1) != gbser_OK) {
-      fatal(MYNAME ": Can't configure port\n");
-    }
-
-    write_packet(PID_SYNC, nullptr, 0);
-    read_packet(PID_ACK, nullptr, 0, 0, false);
-
-    /* nuke data before writing */
-    if (operation == WRITING) {
-      nuke();
-    }
-
-    write_waypoint = serial_write_waypoint;
-    write_track_start = serial_write_track_start;
-    write_track_point = serial_write_track_point;
-    write_track_end = serial_write_track_end;
-    write_route_start = serial_write_route_start;
-    write_route_point = serial_write_route_point;
-    write_route_end = serial_write_route_end;
-  } else {
-    const char* mode = operation == READING ? "r" : "wb";
-    file_handle = gbfopen(name, mode, MYNAME);
-
-    write_waypoint = file_write_waypoint;
-    write_track_start = file_write_track_start;
-    write_track_point = file_write_track_point;
-    write_track_end = file_write_track_end;
-    write_route_start = file_write_route_start;
-    write_route_point = file_write_route_point;
-    write_route_end = file_write_route_end;
-  }
-
-}
-
-static void
-navilink_rd_init(const QString& name)
-{
-  operation = READING;
-  navilink_common_init(name);
-}
-
-static void
-navilink_wr_init(const QString& name)
-{
-  operation = WRITING;
-  navilink_common_init(name);
-}
-
-static void
-navilink_deinit()
-{
-  if (serial_handle) {
-    /* nuke data after reading */
-    if (operation == READING) {
-      nuke();
-    }
-
-    if (poweroff) {
-      write_packet(PID_QUIT, nullptr, 0);
-    }
-
-    gbser_deinit(serial_handle);
-  }
-
-  if (file_handle) {
-    gbfclose(file_handle);
-  }
-
-}
-
-static void
-navilink_read()
-{
-  if (datalog) {
-    if (global_opts.masked_objective & TRKDATAMASK) {
-      if (serial_handle) {
-        serial_read_datalog();
-      } else if (file_handle) {
-        fatal(MYNAME ": Not supported. Use SBP format.\n");
-      }
-    }
-  } else {
-    if (serial_handle) {
-      Waypoint** waypts = nullptr;
-
-      if (global_opts.masked_objective & (WPTDATAMASK|RTEDATAMASK)) {
-        waypts = serial_read_waypoints();
-      }
-
-      if (global_opts.masked_objective & TRKDATAMASK) {
-        serial_read_track();
-      }
-
-      if (global_opts.masked_objective & RTEDATAMASK) {
-        serial_read_routes(waypts);
-      }
-
-      if (waypts) {
-        free_waypoints(waypts);
-      }
-    } else if (file_handle) {
-      file_read();
-    }
-  }
-}
-
-static void
-navilink_write()
-{
-  if (datalog)  {
-    fatal(MYNAME ": Writing to datalog not supported.\n");
-  }
-
-  switch (global_opts.objective) {
-  case trkdata:
-    track_disp_all(write_track_start,
-                   write_track_end,
-                   write_track_point);
-    break;
-  case wptdata:
-    waypt_disp_all(write_waypoint);
-    break;
-  case rtedata:
-    if (serial_handle) {
-      route_waypts = serial_read_waypoints();
-    }
-    route_disp_all(write_route_start,
-                   write_route_end,
-                   write_route_point);
-    if (route_waypts) {
-      free_waypoints(route_waypts);
-      route_waypts = nullptr;
-    }
-    break;
-  default:
-    fatal(MYNAME ": Unknown objective.\n");
-  }
-}
-
-ff_vecs_t navilink_vecs = {
-  ff_type_serial,
-  FF_CAP_RW_ALL,
-  navilink_rd_init,
-  navilink_wr_init,
-  navilink_deinit,
-  navilink_deinit,
-  navilink_read,
-  navilink_write,
-  nullptr,
-  &navilink_args,
-  NULL_POS_OPS
-};
diff --git a/navilink.h b/navilink.h
deleted file mode 100644 (file)
index 3f33e99..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-    Locosys NaviGPS GT-31/BGT-31 common functions.
-
-    Copyright (C) 2008  Rodney Lorrimar <rodney@rodney.id.au>
-    Copyright (C) 2005  Robert Lipe, robertlipe@usa.net
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
- */
-
-#ifndef NAVILINK_H_INCLUDED_
-#define NAVILINK_H_INCLUDED_
-
-#include <ctime>
-#include "defs.h"
-
-#define SBP_RECORD_LEN 32
-
-/* defined in navilink.c */
-Waypoint* navilink_decode_logpoint(const unsigned char* buffer);
-unsigned navilink_checksum_packet(const unsigned char* packet, unsigned length);
-
-/* defined in sbn.c */
-bool locosys_decode_file_id(char* header, size_t len);
-
-
-#ifdef THIS_IS_ONLY_FOR_REFERENCE
-/* Locosys SBP and SBN structures */
-
-typedef __packed struct {
-  UINT8 HDOP;        /* HDOP [0..51] with resolution 0.2 */
-  UINT8 SVIDCnt;        /* Number of SVs in solution [0 to 12] */
-  UINT16 UtcSec;        /* UTC Second [0 to 59] in seconds with resolution 0.001 */
-  UINT32 date_time_UTC_packed; /* refer to protocol doc*/
-  UINT32 SVIDList;    /* SVs in solution:  Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */
-  INT32 Lat;            /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */
-  INT32 Lon;            /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */
-  INT32 AltCM;            /* Altitude from Mean Sea Level in centi meters */
-  UINT16 Sog;            /* Speed Over Ground in m/sec with resolution 0.01 */
-  UINT16 Cog;            /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */
-  INT16 ClmbRte;        /* Climb rate in m/sec with resolution 0.01 */
-  UINT8 bitFlags;     /* bitFlags, default 0x00,    bit 0=1 indicate the first point after power on */
-  UINT8 reserved;
-} T_SBP;
-
-typedef struct __packed {
-  UINT8 Mid;
-  UINT16 Valid;
-  UINT16 Mode;            /* Nav Mode:  bit map as follows:
-                            *  Bits 2-0:  GPS Fix Type
-                            *    000   =  No Nav
-                            *    001   =  1 SV solution
-                            *    010   =  2 SV solution
-                            *    011   =  3 SV solution (2D)
-                            *    100   =  4 or more SV solution (3D)
-                            *    101   =  Least Square 2D solution
-                            *    110   =  Least Square 3D solution
-                            *    111   =  DR solution (no SV)
-                            *  Bit  3  :  1 = Trickle Power ON
-                            *  Bits 5-4:  Altitude Hold
-                            *    00    =  No Altitude Hold
-                            *    01    =  Altitude Hold using altitude from KF
-                            *    10    =  Altitude Hold using altitude from user
-                            *    11    =  forced altitude
-                            *  Bit 6   :  1 = DOP exceeded
-                            *  Bit 7   :  1 = DGPS correction applied
-                            *  Bit 8   :
-                            *    1     = Sensor-based DR
-                            *    0     = Velocity DR, if bits 2-0 = 111
-                            *          = see bits 15-14, if bits 2-0 != 111
-                            *  Bit 9   :  1 = Solution validated
-                            *  Bit 10  :  1 = Velocity DR Timeout
-                            *  Bit 11  :  1 = Solution edited by UI
-                            *  Bit 12  :  1 = Velocity invalid
-                            *  Bit 13  :  1 = Altitude Hold disabled
-                            *  Bits 15-14: SiRFDrive DR Status (applicable only when bit 8=0)
-                            *    00    =  GPS Only
-                            *    01    =  Calibrating
-                            *    10    =  DR sensor error
-                            *    11    =  DR Test mode
-                            */
-  UINT16 Week;            /* Extended Week Number */
-  UINT32 TOW;             /* Time of Week [0 to 604800] in seconds with resolution 0.001 */
-  UINT16 UtcYr;           /* UTC Year   [1980 to 3000] */
-  UINT8  UtcMth;          /* UTC Month  [1 to 12] */
-  UINT8  UtcDay;          /* UTC Day    [1 to 31] */
-  UINT8  UtcHr;           /* UTC Hour   [0 to 23] */
-  UINT8  UtcMin;          /* UTC Minute [0 to 59] */
-  UINT16 UtcSec;          /* UTC Second [0 to 59] in seconds with resolution 0.001 */
-  UINT32 SVIDList;        /* SVs in solution:  Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */
-
-  INT32  Lat;             /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */
-  INT32  Lon;             /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */
-  INT32  AltE;            /* Altitude from Ellipsoid in meters with resolution 0.01 */
-  INT32  AltM;            /* Altitude from Mean Sea Level in meters with resolution 0.01 */
-  UINT8  Datum;           /* Map datum */
-  UINT16 Sog;             /* Speed Over Ground in m/sec with resolution 0.01 */
-  UINT16 Cog;             /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */
-  INT16  MagVar;          /* Magnetic Variation - Reserved */
-  INT16  ClmbRte;         /* Climb rate in m/sec with resolution 0.01 */
-  INT16  HdRte;           /* Heading Rate in deg/sec with resolution 0.01 (SiRFDrive only) */
-  UINT32 Ehpe;            /* Expected Horizontal Position Error in meters with resolution 0.01 */
-  UINT32 Evpe;            /* Expected Horizontal Vertical Error in meters with resolution 0.01 */
-  UINT32 Ete;             /* Expected Time Error in meters with resolution 0.01 (SiRFDrive only) - Reserved */
-  UINT16 Ehve;            /* Expected Horizontal Velocity Error in m/sec with resolution 0.01 (SiRFDrive only) */
-  INT32  ClkBias;         /* Clock Bias in meters with resolution 0.01 */
-  UINT32 ClkBiasE;        /* Clock Bias Error in meters with resolution 0.01 (SiRFDrive only) */
-  INT32  ClkDrift;        /* Clock Drift in m/sec with resolution 0.01 */
-  UINT32 ClkDriftE;       /* Clock Drift in m/sec with resolution 0.01 (SiRFDrive only) */
-  UINT32 Trvled;          /* Distance Traveled since reset in meters (SiRFDrive only) */
-  UINT16 TrvledE;         /* Distance Traveled Error in meters (SiRFDrive only) */
-  UINT16 HdE;             /* Heading Error [0 to 180] in degrees with resolution 0.01 (SiRFDrive only) */
-  UINT8  SVIDCnt;         /* Number of SVs in solution [0 to 12] */
-  UINT8  HDOP;            /* HDOP [0..51] with resolution 0.2 */
-  UINT8  Reserved;        /* Reserved */
-
-  UINT16 ufSog;             /* Speed Over Ground in m/sec with resolution 0.01 ,unfiltered*/
-  UINT16 ufCog;             /* Course Over Ground [0 to 360] in degrees with resolution 0.01, unfiltered  */
-
-}  T_SBN_REC;
-
-#endif
-
-#endif  // NAVILINK_H_INCLUDED_
index ee6c7a35f873a0826efcfcdad7dcfedf3ee040f5..c027f1fa41d08e5b692798a6245651c8f45fc4ca 100644 (file)
@@ -39,9 +39,6 @@ mtk           MTK Logger (iBlue 747,Qstarz BT-1000,...) download
 tpg    tpg     National Geographic Topo .tpg (waypoints)
 tpo2   tpo     National Geographic Topo 2.x .tpo
 tpo3   tpo     National Geographic Topo 3.x/4.x .tpo
-navilink               NaviGPS GT-11/BGT-11 Download
-sbp    sbp     NaviGPS GT-31/BGT-31 datalogger (.sbp)
-sbn    sbn     NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)
 nmea           NMEA 0183 sentences
 osm    osm     OpenStreetMap data files
 ozi            OziExplorer
index 64f40e9d43fc4f94791ea81970a0498940755e06..88b83cd13ae40045a7871a42318faf9246844b1f 100644 (file)
@@ -45,9 +45,6 @@ serial        mtk             MTK Logger (iBlue 747,Qstarz BT-1000,...) download
 file   tpg     tpg     National Geographic Topo .tpg (waypoints)
 file   tpo2    tpo     National Geographic Topo 2.x .tpo
 file   tpo3    tpo     National Geographic Topo 3.x/4.x .tpo
-serial navilink                NaviGPS GT-11/BGT-11 Download
-file   sbp     sbp     NaviGPS GT-31/BGT-31 datalogger (.sbp)
-file   sbn     sbn     NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)
 file   nmea            NMEA 0183 sentences
 file   osm     osm     OpenStreetMap data files
 file   ozi             OziExplorer
index 5b2cc187e834b883880a543016f8bab41c853d9a..1e9944c12d002725998d2a8c4b971beab68f4087 100644 (file)
@@ -45,9 +45,6 @@ serial        r-r---  mtk             MTK Logger (iBlue 747,Qstarz BT-1000,...) download
 file   rw----  tpg     tpg     National Geographic Topo .tpg (waypoints)
 file   --r---  tpo2    tpo     National Geographic Topo 2.x .tpo
 file   r-r-r-  tpo3    tpo     National Geographic Topo 3.x/4.x .tpo
-serial rwrwrw  navilink                NaviGPS GT-11/BGT-11 Download
-file   --r---  sbp     sbp     NaviGPS GT-31/BGT-31 datalogger (.sbp)
-file   --r---  sbn     sbn     NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)
 file   rwrw--  nmea            NMEA 0183 sentences
 file   rw-wrw  osm     osm     OpenStreetMap data files
 file   rwrwrw  ozi             OziExplorer
index 524719f6f7ac13a4577d6d25b7c37060f646800e..427a4bc0ec109ef6c039e37a11da3ee5bccc99b9 100644 (file)
@@ -574,24 +574,6 @@ file       --r---  tpo2    tpo     National Geographic Topo 2.x .tpo       tpo2
        https://www.gpsbabel.org/WEB_DOC_DIR/fmt_tpo2.html
 file   r-r-r-  tpo3    tpo     National Geographic Topo 3.x/4.x .tpo   tpo3
        https://www.gpsbabel.org/WEB_DOC_DIR/fmt_tpo3.html
-serial rwrwrw  navilink                NaviGPS GT-11/BGT-11 Download   navilink
-       https://www.gpsbabel.org/WEB_DOC_DIR/fmt_navilink.html
-option navilink        nuketrk Delete all track points boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/fmt_navilink.html#fmt_navilink_o_nuketrk
-
-option navilink        nukerte Delete all routes       boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/fmt_navilink.html#fmt_navilink_o_nukerte
-
-option navilink        nukewpt Delete all waypoints    boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/fmt_navilink.html#fmt_navilink_o_nukewpt
-
-option navilink        nukedlg Clear the datalog       boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/fmt_navilink.html#fmt_navilink_o_nukedlg
-
-option navilink        datalog Read from datalogger buffer     boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/fmt_navilink.html#fmt_navilink_o_datalog
-
-option navilink        power_off       Command unit to power itself down       boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/fmt_navilink.html#fmt_navilink_o_power_off
-
-file   --r---  sbp     sbp     NaviGPS GT-31/BGT-31 datalogger (.sbp)  sbp
-       https://www.gpsbabel.org/WEB_DOC_DIR/fmt_sbp.html
-file   --r---  sbn     sbn     NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn) sbn
-       https://www.gpsbabel.org/WEB_DOC_DIR/fmt_sbn.html
 file   rwrw--  nmea            NMEA 0183 sentences     nmea
        https://www.gpsbabel.org/WEB_DOC_DIR/fmt_nmea.html
 option nmea    snlen   Max length of waypoint name to write    integer 6       1       64      https://www.gpsbabel.org/WEB_DOC_DIR/fmt_nmea.html#fmt_nmea_o_snlen
index 54552ba97dc4475b8fd64389e32123b65726035c..18edf00d5504909d6d9b879ca0e31cc4da6effef 100644 (file)
@@ -282,15 +282,6 @@ File Types (-i and -o options):
          datum                 Datum (default=NAD27)
        tpo2                  National Geographic Topo 2.x .tpo
        tpo3                  National Geographic Topo 3.x/4.x .tpo
-       navilink              NaviGPS GT-11/BGT-11 Download
-         nuketrk               (0/1) Delete all track points
-         nukerte               (0/1) Delete all routes
-         nukewpt               (0/1) Delete all waypoints
-         nukedlg               (0/1) Clear the datalog
-         datalog               (0/1) Read from datalogger buffer
-         power_off             (0/1) Command unit to power itself down
-       sbp                   NaviGPS GT-31/BGT-31 datalogger (.sbp)
-       sbn                   NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)
        nmea                  NMEA 0183 sentences
          snlen                 Max length of waypoint name to write
          gprmc                 (0/1) Read/write GPRMC sentences
diff --git a/reference/navilink_tracks.gpx b/reference/navilink_tracks.gpx
deleted file mode 100644 (file)
index 05e81d5..0000000
+++ /dev/null
@@ -1,2079 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
-  <time>1970-01-01T00:00:00Z</time>
-  <bounds minlat="51.758580000" minlon="-0.012070000" maxlat="51.764718300" maxlon="-0.003189900"/>
-  <trk>
-    <trkseg>
-      <trkpt lat="51.758580000" lon="-0.012070000">
-        <ele>0.000</ele>
-        <time>2007-10-03T16:01:20Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758580000" lon="-0.012070000">
-        <ele>0.000</ele>
-        <time>2007-10-03T16:01:22Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758580000" lon="-0.012070000">
-        <ele>0.000</ele>
-        <time>2007-10-03T16:01:24Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758580000" lon="-0.012033300">
-        <ele>32.004</ele>
-        <time>2007-10-03T16:01:46Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758581600" lon="-0.012033300">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:01:48Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758581600" lon="-0.012033300">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:01:50Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758583300" lon="-0.012033300">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:01:53Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758583300" lon="-0.012031600">
-        <ele>34.138</ele>
-        <time>2007-10-03T16:01:55Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758588300" lon="-0.012023300">
-        <ele>33.223</ele>
-        <time>2007-10-03T16:01:57Z</time>
-        <course>23.000000</course>
-        <speed>0.555556</speed>
-      </trkpt>
-      <trkpt lat="51.758603300" lon="-0.011998300">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:01:59Z</time>
-        <course>41.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.758623300" lon="-0.011965000">
-        <ele>32.614</ele>
-        <time>2007-10-03T16:02:01Z</time>
-        <course>47.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758641600" lon="-0.011926600">
-        <ele>32.309</ele>
-        <time>2007-10-03T16:02:03Z</time>
-        <course>57.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758661600" lon="-0.011888300">
-        <ele>32.614</ele>
-        <time>2007-10-03T16:02:05Z</time>
-        <course>47.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758683300" lon="-0.011851600">
-        <ele>32.614</ele>
-        <time>2007-10-03T16:02:07Z</time>
-        <course>57.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758700000" lon="-0.011808300">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:02:09Z</time>
-        <course>63.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758715000" lon="-0.011763300">
-        <ele>33.528</ele>
-        <time>2007-10-03T16:02:11Z</time>
-        <course>61.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758730000" lon="-0.011720000">
-        <ele>33.833</ele>
-        <time>2007-10-03T16:02:13Z</time>
-        <course>63.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758743300" lon="-0.011676600">
-        <ele>34.138</ele>
-        <time>2007-10-03T16:02:15Z</time>
-        <course>63.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758758300" lon="-0.011631600">
-        <ele>34.747</ele>
-        <time>2007-10-03T16:02:17Z</time>
-        <course>64.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758771600" lon="-0.011583300">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:02:19Z</time>
-        <course>69.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758783300" lon="-0.011538300">
-        <ele>35.357</ele>
-        <time>2007-10-03T16:02:21Z</time>
-        <course>71.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758793300" lon="-0.011490000">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:02:23Z</time>
-        <course>71.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758803300" lon="-0.011441600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:02:25Z</time>
-        <course>78.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758806600" lon="-0.011413300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:02:27Z</time>
-        <course>76.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758821600" lon="-0.011333300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:02:29Z</time>
-        <course>78.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758828300" lon="-0.011276600">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:02:31Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758835000" lon="-0.011213300">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:02:33Z</time>
-        <course>79.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758841600" lon="-0.011158300">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:02:35Z</time>
-        <course>78.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758845000" lon="-0.011108300">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:02:37Z</time>
-        <course>80.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758848300" lon="-0.011070000">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:02:39Z</time>
-        <course>83.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758851600" lon="-0.011028300">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:02:41Z</time>
-        <course>81.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758860000" lon="-0.010986600">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:02:43Z</time>
-        <course>78.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758865000" lon="-0.010944900">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:02:45Z</time>
-        <course>86.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758866600" lon="-0.010921600">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:02:47Z</time>
-        <course>82.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758875000" lon="-0.010856600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:02:49Z</time>
-        <course>80.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758880000" lon="-0.010806600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:02:51Z</time>
-        <course>82.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758883300" lon="-0.010756600">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:02:53Z</time>
-        <course>82.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758888300" lon="-0.010708300">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:02:55Z</time>
-        <course>82.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758891600" lon="-0.010659900">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:02:57Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758895000" lon="-0.010615000">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:02:59Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758896600" lon="-0.010570000">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:03:01Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758899900" lon="-0.010520000">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:03:03Z</time>
-        <course>83.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758908300" lon="-0.010473300">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:03:05Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758913300" lon="-0.010428300">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:03:07Z</time>
-        <course>86.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758916600" lon="-0.010380000">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:03:09Z</time>
-        <course>86.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758921600" lon="-0.010331600">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:03:11Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758925000" lon="-0.010281600">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:03:13Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758929900" lon="-0.010233300">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:03:15Z</time>
-        <course>83.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758933300" lon="-0.010186600">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:03:17Z</time>
-        <course>81.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758940000" lon="-0.010141600">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:03:19Z</time>
-        <course>85.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758946600" lon="-0.010093300">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:03:21Z</time>
-        <course>85.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758951600" lon="-0.010045000">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:03:23Z</time>
-        <course>78.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758958300" lon="-0.009998300">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:03:25Z</time>
-        <course>82.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758963300" lon="-0.009951600">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:03:27Z</time>
-        <course>79.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758966600" lon="-0.009903300">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:03:29Z</time>
-        <course>80.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758968300" lon="-0.009858300">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:03:31Z</time>
-        <course>84.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758973300" lon="-0.009815000">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:03:33Z</time>
-        <course>75.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758980000" lon="-0.009763300">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:03:35Z</time>
-        <course>79.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758988300" lon="-0.009711600">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:03:37Z</time>
-        <course>78.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758991600" lon="-0.009684900">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:03:39Z</time>
-        <course>86.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758991600" lon="-0.009684900">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:03:41Z</time>
-        <course>86.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758971600" lon="-0.009575000">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:03:43Z</time>
-        <course>94.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.758971600" lon="-0.009575000">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:03:45Z</time>
-        <course>94.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.758971600" lon="-0.009575000">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:03:47Z</time>
-        <course>94.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759036600" lon="-0.009298300">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:03:56Z</time>
-        <course>57.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759036600" lon="-0.009298300">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:03:58Z</time>
-        <course>57.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759070000" lon="-0.009225000">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:04:00Z</time>
-        <course>55.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759083300" lon="-0.009181600">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:04:02Z</time>
-        <course>68.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759093300" lon="-0.009143300">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:04:04Z</time>
-        <course>59.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759108300" lon="-0.009113300">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:04:06Z</time>
-        <course>50.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759108300" lon="-0.009113300">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:04:08Z</time>
-        <course>50.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759133300" lon="-0.009025000">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:04:10Z</time>
-        <course>59.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759146600" lon="-0.008981600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:04:12Z</time>
-        <course>64.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759156600" lon="-0.008935000">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:04:14Z</time>
-        <course>70.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759165000" lon="-0.008900000">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:04:16Z</time>
-        <course>68.000000</course>
-        <speed>0.555556</speed>
-      </trkpt>
-      <trkpt lat="51.759176600" lon="-0.008868300">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:04:18Z</time>
-        <course>56.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759195000" lon="-0.008833300">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:04:20Z</time>
-        <course>51.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759213300" lon="-0.008791600">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:04:22Z</time>
-        <course>63.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759228300" lon="-0.008743300">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:04:24Z</time>
-        <course>64.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759235000" lon="-0.008716600">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:04:26Z</time>
-        <course>64.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759235000" lon="-0.008716600">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:04:28Z</time>
-        <course>64.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759293300" lon="-0.008516600">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:04:42Z</time>
-        <course>64.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759293300" lon="-0.008518300">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:04:44Z</time>
-        <course>64.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759301600" lon="-0.008520000">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:04:46Z</time>
-        <course>64.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759301600" lon="-0.008520000">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:04:48Z</time>
-        <course>64.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759311600" lon="-0.008510000">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:04:51Z</time>
-        <course>64.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759353300" lon="-0.008471600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:04:53Z</time>
-        <course>57.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759370000" lon="-0.008436600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:04:55Z</time>
-        <course>53.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759385000" lon="-0.008400000">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:04:57Z</time>
-        <course>57.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759403300" lon="-0.008360000">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:04:59Z</time>
-        <course>53.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759421600" lon="-0.008323300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:05:01Z</time>
-        <course>52.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759438300" lon="-0.008288300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:05:03Z</time>
-        <course>50.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759456600" lon="-0.008256600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:05:05Z</time>
-        <course>50.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759473300" lon="-0.008225000">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:05:07Z</time>
-        <course>48.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759490000" lon="-0.008195000">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:05:09Z</time>
-        <course>50.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759508300" lon="-0.008160000">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:05:11Z</time>
-        <course>45.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759528300" lon="-0.008126600">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:05:13Z</time>
-        <course>46.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759546600" lon="-0.008091600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:05:15Z</time>
-        <course>47.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759555000" lon="-0.008073300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:05:17Z</time>
-        <course>56.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759565000" lon="-0.008035000">
-        <ele>35.357</ele>
-        <time>2007-10-03T16:05:19Z</time>
-        <course>56.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759565000" lon="-0.008035000">
-        <ele>35.357</ele>
-        <time>2007-10-03T16:05:21Z</time>
-        <course>56.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759573300" lon="-0.008025000">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:05:23Z</time>
-        <course>107.000000</course>
-        <speed>0.555556</speed>
-      </trkpt>
-      <trkpt lat="51.759561600" lon="-0.008011600">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:05:25Z</time>
-        <course>126.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759556600" lon="-0.007985000">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:05:27Z</time>
-        <course>103.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759544900" lon="-0.007928300">
-        <ele>34.747</ele>
-        <time>2007-10-03T16:05:30Z</time>
-        <course>104.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759546600" lon="-0.007891600">
-        <ele>34.442</ele>
-        <time>2007-10-03T16:05:32Z</time>
-        <course>81.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759565000" lon="-0.007861600">
-        <ele>33.833</ele>
-        <time>2007-10-03T16:05:34Z</time>
-        <course>18.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759591600" lon="-0.007848300">
-        <ele>33.528</ele>
-        <time>2007-10-03T16:05:36Z</time>
-        <course>23.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.759623300" lon="-0.007840000">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:05:38Z</time>
-        <course>20.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759623300" lon="-0.007840000">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:05:40Z</time>
-        <course>20.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759623300" lon="-0.007840000">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:05:42Z</time>
-        <course>20.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759683300" lon="-0.007813300">
-        <ele>32.004</ele>
-        <time>2007-10-03T16:05:43Z</time>
-        <course>18.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.759683300" lon="-0.007813300">
-        <ele>32.004</ele>
-        <time>2007-10-03T16:05:46Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759786600" lon="-0.007696600">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:05:55Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759795000" lon="-0.007680000">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:05:57Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759795000" lon="-0.007680000">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:05:59Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759880000" lon="-0.007583300">
-        <ele>31.394</ele>
-        <time>2007-10-03T16:06:05Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759906600" lon="-0.007560000">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:06:07Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759906600" lon="-0.007560000">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:06:09Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.759906600" lon="-0.007560000">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:06:11Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760084900" lon="-0.007390000">
-        <ele>31.394</ele>
-        <time>2007-10-03T16:06:22Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760084900" lon="-0.007390000">
-        <ele>31.394</ele>
-        <time>2007-10-03T16:06:24Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760084900" lon="-0.007390000">
-        <ele>31.394</ele>
-        <time>2007-10-03T16:06:26Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760136600" lon="-0.007323300">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:06:28Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760156600" lon="-0.007321600">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:06:30Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760156600" lon="-0.007321600">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:06:32Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760156600" lon="-0.007321600">
-        <ele>31.699</ele>
-        <time>2007-10-03T16:06:34Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760598300" lon="-0.007103300">
-        <ele>29.566</ele>
-        <time>2007-10-03T16:07:08Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760690000" lon="-0.007025000">
-        <ele>33.223</ele>
-        <time>2007-10-03T16:07:10Z</time>
-        <course>15.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760678300" lon="-0.007036600">
-        <ele>32.309</ele>
-        <time>2007-10-03T16:07:12Z</time>
-        <course>16.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760678300" lon="-0.007036600">
-        <ele>32.309</ele>
-        <time>2007-10-03T16:07:14Z</time>
-        <course>16.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760678300" lon="-0.007036600">
-        <ele>32.309</ele>
-        <time>2007-10-03T16:07:16Z</time>
-        <course>16.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760773300" lon="-0.007003300">
-        <ele>34.442</ele>
-        <time>2007-10-03T16:07:18Z</time>
-        <course>17.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760800000" lon="-0.006995000">
-        <ele>34.747</ele>
-        <time>2007-10-03T16:07:20Z</time>
-        <course>14.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760825000" lon="-0.006983300">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:07:22Z</time>
-        <course>16.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760836600" lon="-0.006976600">
-        <ele>34.747</ele>
-        <time>2007-10-03T16:07:24Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760836600" lon="-0.006976600">
-        <ele>34.747</ele>
-        <time>2007-10-03T16:07:26Z</time>
-        <course>18.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.760961600" lon="-0.006853300">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:07:34Z</time>
-        <course>38.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760970000" lon="-0.006816600">
-        <ele>32.918</ele>
-        <time>2007-10-03T16:07:36Z</time>
-        <course>61.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760978300" lon="-0.006780000">
-        <ele>32.309</ele>
-        <time>2007-10-03T16:07:38Z</time>
-        <course>62.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.760989900" lon="-0.006756600">
-        <ele>32.004</ele>
-        <time>2007-10-03T16:07:40Z</time>
-        <course>40.000000</course>
-        <speed>0.555556</speed>
-      </trkpt>
-      <trkpt lat="51.761019900" lon="-0.006718300">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:08:28Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761021600" lon="-0.006713300">
-        <ele>38.710</ele>
-        <time>2007-10-03T16:08:29Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761031600" lon="-0.006715000">
-        <ele>39.929</ele>
-        <time>2007-10-03T16:08:32Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761031600" lon="-0.006713300">
-        <ele>39.319</ele>
-        <time>2007-10-03T16:08:33Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761038300" lon="-0.006716600">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:08:36Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761038300" lon="-0.006715000">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:08:37Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761038300" lon="-0.006705000">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:08:40Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761038300" lon="-0.006703300">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:08:41Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761036600" lon="-0.006701600">
-        <ele>43.586</ele>
-        <time>2007-10-03T16:08:43Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761033300" lon="-0.006710000">
-        <ele>45.110</ele>
-        <time>2007-10-03T16:08:46Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761030000" lon="-0.006715000">
-        <ele>45.110</ele>
-        <time>2007-10-03T16:08:47Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761023300" lon="-0.006730000">
-        <ele>45.110</ele>
-        <time>2007-10-03T16:08:50Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761021600" lon="-0.006735000">
-        <ele>44.806</ele>
-        <time>2007-10-03T16:08:51Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761019900" lon="-0.006745000">
-        <ele>43.586</ele>
-        <time>2007-10-03T16:08:54Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761018300" lon="-0.006746600">
-        <ele>42.977</ele>
-        <time>2007-10-03T16:08:55Z</time>
-        <course>0.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761026600" lon="-0.006726600">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:08:58Z</time>
-        <course>35.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761040000" lon="-0.006715000">
-        <ele>42.367</ele>
-        <time>2007-10-03T16:08:59Z</time>
-        <course>28.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761085000" lon="-0.006695000">
-        <ele>42.672</ele>
-        <time>2007-10-03T16:09:02Z</time>
-        <course>16.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761100000" lon="-0.006695000">
-        <ele>42.367</ele>
-        <time>2007-10-03T16:09:03Z</time>
-        <course>17.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761145000" lon="-0.006681600">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:09:06Z</time>
-        <course>21.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761161600" lon="-0.006670000">
-        <ele>41.758</ele>
-        <time>2007-10-03T16:09:07Z</time>
-        <course>22.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761205000" lon="-0.006635000">
-        <ele>41.758</ele>
-        <time>2007-10-03T16:09:10Z</time>
-        <course>29.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761216600" lon="-0.006623300">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:09:11Z</time>
-        <course>34.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761229900" lon="-0.006610000">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:09:13Z</time>
-        <course>36.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761288300" lon="-0.006538300">
-        <ele>40.843</ele>
-        <time>2007-10-03T16:09:16Z</time>
-        <course>65.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761295000" lon="-0.006515000">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:09:17Z</time>
-        <course>65.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761311600" lon="-0.006446600">
-        <ele>40.843</ele>
-        <time>2007-10-03T16:09:20Z</time>
-        <course>68.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761316600" lon="-0.006425000">
-        <ele>40.843</ele>
-        <time>2007-10-03T16:09:21Z</time>
-        <course>71.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761326600" lon="-0.006354900">
-        <ele>40.843</ele>
-        <time>2007-10-03T16:09:24Z</time>
-        <course>78.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761330000" lon="-0.006330000">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:09:25Z</time>
-        <course>80.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761336600" lon="-0.006258300">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:09:28Z</time>
-        <course>82.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761338300" lon="-0.006233300">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:09:29Z</time>
-        <course>85.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761353300" lon="-0.006171600">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:09:32Z</time>
-        <course>53.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761363300" lon="-0.006156600">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:09:33Z</time>
-        <course>37.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761403300" lon="-0.006141600">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:09:36Z</time>
-        <course>5.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761418300" lon="-0.006140000">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:09:37Z</time>
-        <course>4.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761454900" lon="-0.006153300">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:09:40Z</time>
-        <course>288.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761461600" lon="-0.006169900">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:09:41Z</time>
-        <course>290.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761465000" lon="-0.006216600">
-        <ele>41.758</ele>
-        <time>2007-10-03T16:09:44Z</time>
-        <course>279.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761463300" lon="-0.006218300">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:09:46Z</time>
-        <course>279.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761465000" lon="-0.006221600">
-        <ele>42.367</ele>
-        <time>2007-10-03T16:09:47Z</time>
-        <course>295.000000</course>
-        <speed>0.555556</speed>
-      </trkpt>
-      <trkpt lat="51.761481600" lon="-0.006266600">
-        <ele>42.672</ele>
-        <time>2007-10-03T16:09:50Z</time>
-        <course>299.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761486600" lon="-0.006286600">
-        <ele>42.672</ele>
-        <time>2007-10-03T16:09:51Z</time>
-        <course>300.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761510000" lon="-0.006341600">
-        <ele>43.282</ele>
-        <time>2007-10-03T16:09:54Z</time>
-        <course>308.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761518300" lon="-0.006360000">
-        <ele>43.282</ele>
-        <time>2007-10-03T16:09:55Z</time>
-        <course>308.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761543300" lon="-0.006410000">
-        <ele>43.586</ele>
-        <time>2007-10-03T16:09:58Z</time>
-        <course>316.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761555000" lon="-0.006423300">
-        <ele>43.586</ele>
-        <time>2007-10-03T16:09:59Z</time>
-        <course>323.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761591600" lon="-0.006461600">
-        <ele>43.282</ele>
-        <time>2007-10-03T16:10:02Z</time>
-        <course>327.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761603300" lon="-0.006475000">
-        <ele>43.282</ele>
-        <time>2007-10-03T16:10:03Z</time>
-        <course>320.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761638300" lon="-0.006516600">
-        <ele>43.586</ele>
-        <time>2007-10-03T16:10:06Z</time>
-        <course>327.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761651600" lon="-0.006530000">
-        <ele>43.586</ele>
-        <time>2007-10-03T16:10:07Z</time>
-        <course>331.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761688300" lon="-0.006571600">
-        <ele>43.891</ele>
-        <time>2007-10-03T16:10:10Z</time>
-        <course>324.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761700000" lon="-0.006585000">
-        <ele>44.196</ele>
-        <time>2007-10-03T16:10:11Z</time>
-        <course>327.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761738300" lon="-0.006613300">
-        <ele>44.501</ele>
-        <time>2007-10-03T16:10:14Z</time>
-        <course>342.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761765000" lon="-0.006623300">
-        <ele>44.196</ele>
-        <time>2007-10-03T16:10:16Z</time>
-        <course>353.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761780000" lon="-0.006621600">
-        <ele>44.196</ele>
-        <time>2007-10-03T16:10:17Z</time>
-        <course>3.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761823300" lon="-0.006608300">
-        <ele>43.282</ele>
-        <time>2007-10-03T16:10:20Z</time>
-        <course>15.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761836600" lon="-0.006600000">
-        <ele>42.672</ele>
-        <time>2007-10-03T16:10:21Z</time>
-        <course>19.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761878300" lon="-0.006576600">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:10:24Z</time>
-        <course>20.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761891600" lon="-0.006570000">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:10:25Z</time>
-        <course>20.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.761913300" lon="-0.006555000">
-        <ele>41.758</ele>
-        <time>2007-10-03T16:10:28Z</time>
-        <course>25.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.761936600" lon="-0.006541600">
-        <ele>41.758</ele>
-        <time>2007-10-03T16:10:29Z</time>
-        <course>26.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761971600" lon="-0.006508300">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:10:32Z</time>
-        <course>26.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.761983300" lon="-0.006496600">
-        <ele>42.367</ele>
-        <time>2007-10-03T16:10:33Z</time>
-        <course>29.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762020000" lon="-0.006470000">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:10:36Z</time>
-        <course>23.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762033300" lon="-0.006460000">
-        <ele>42.367</ele>
-        <time>2007-10-03T16:10:37Z</time>
-        <course>22.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762058300" lon="-0.006445000">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:10:39Z</time>
-        <course>22.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762080000" lon="-0.006429900">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:10:41Z</time>
-        <course>29.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762110000" lon="-0.006400000">
-        <ele>40.234</ele>
-        <time>2007-10-03T16:10:44Z</time>
-        <course>29.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762123300" lon="-0.006390000">
-        <ele>40.234</ele>
-        <time>2007-10-03T16:10:45Z</time>
-        <course>29.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762151600" lon="-0.006373300">
-        <ele>40.234</ele>
-        <time>2007-10-03T16:10:47Z</time>
-        <course>21.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762193300" lon="-0.006348300">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:10:50Z</time>
-        <course>23.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762206600" lon="-0.006338300">
-        <ele>40.843</ele>
-        <time>2007-10-03T16:10:51Z</time>
-        <course>23.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762249900" lon="-0.006310000">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:10:54Z</time>
-        <course>27.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762261600" lon="-0.006300000">
-        <ele>40.843</ele>
-        <time>2007-10-03T16:10:55Z</time>
-        <course>27.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762296600" lon="-0.006268300">
-        <ele>39.319</ele>
-        <time>2007-10-03T16:10:58Z</time>
-        <course>30.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762308300" lon="-0.006258300">
-        <ele>38.710</ele>
-        <time>2007-10-03T16:10:59Z</time>
-        <course>31.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762346600" lon="-0.006216600">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:11:02Z</time>
-        <course>40.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762356600" lon="-0.006200000">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:11:03Z</time>
-        <course>45.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762381600" lon="-0.006141600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:11:06Z</time>
-        <course>64.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762388300" lon="-0.006120000">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:11:07Z</time>
-        <course>73.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762403300" lon="-0.006045000">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:11:10Z</time>
-        <course>77.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762408300" lon="-0.006016600">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:11:11Z</time>
-        <course>77.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762423300" lon="-0.005935000">
-        <ele>38.710</ele>
-        <time>2007-10-03T16:11:14Z</time>
-        <course>74.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762431600" lon="-0.005888300">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:11:16Z</time>
-        <course>69.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762436600" lon="-0.005865000">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:11:17Z</time>
-        <course>69.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762455000" lon="-0.005801600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:11:20Z</time>
-        <course>56.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762463300" lon="-0.005783300">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:11:21Z</time>
-        <course>58.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762486600" lon="-0.005726600">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:11:24Z</time>
-        <course>48.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762496600" lon="-0.005710000">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:11:25Z</time>
-        <course>49.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762528300" lon="-0.005671600">
-        <ele>35.357</ele>
-        <time>2007-10-03T16:11:28Z</time>
-        <course>32.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762540000" lon="-0.005661600">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:11:29Z</time>
-        <course>34.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762578300" lon="-0.005633300">
-        <ele>35.357</ele>
-        <time>2007-10-03T16:11:32Z</time>
-        <course>24.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762593300" lon="-0.005626600">
-        <ele>35.052</ele>
-        <time>2007-10-03T16:11:33Z</time>
-        <course>20.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762621600" lon="-0.005615000">
-        <ele>34.747</ele>
-        <time>2007-10-03T16:11:35Z</time>
-        <course>17.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762653300" lon="-0.005601600">
-        <ele>35.357</ele>
-        <time>2007-10-03T16:11:37Z</time>
-        <course>13.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762703300" lon="-0.005595000">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:11:40Z</time>
-        <course>359.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762720000" lon="-0.005593300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:11:41Z</time>
-        <course>1.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762768300" lon="-0.005595000">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:11:44Z</time>
-        <course>357.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762800000" lon="-0.005601600">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:11:46Z</time>
-        <course>353.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762815000" lon="-0.005605000">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:11:47Z</time>
-        <course>353.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762861600" lon="-0.005611600">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:11:50Z</time>
-        <course>0.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762876600" lon="-0.005608300">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:11:51Z</time>
-        <course>10.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.762918300" lon="-0.005603300">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:11:54Z</time>
-        <course>92.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762931600" lon="-0.005603300">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:11:55Z</time>
-        <course>46.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.762953300" lon="-0.005605000">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:11:58Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762953300" lon="-0.005605000">
-        <ele>38.710</ele>
-        <time>2007-10-03T16:11:59Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762953300" lon="-0.005605000">
-        <ele>38.710</ele>
-        <time>2007-10-03T16:12:02Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762956600" lon="-0.005601600">
-        <ele>38.710</ele>
-        <time>2007-10-03T16:12:03Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762956600" lon="-0.005600000">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:12:06Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762956600" lon="-0.005601600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:12:07Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762953300" lon="-0.005606600">
-        <ele>33.833</ele>
-        <time>2007-10-03T16:12:10Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762951600" lon="-0.005610000">
-        <ele>33.528</ele>
-        <time>2007-10-03T16:12:11Z</time>
-        <course>186.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762965000" lon="-0.005631600">
-        <ele>33.223</ele>
-        <time>2007-10-03T16:12:14Z</time>
-        <course>326.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.762998300" lon="-0.005711600">
-        <ele>34.138</ele>
-        <time>2007-10-03T16:12:16Z</time>
-        <course>309.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763001600" lon="-0.005720000">
-        <ele>34.138</ele>
-        <time>2007-10-03T16:12:18Z</time>
-        <course>312.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.763025000" lon="-0.005721600">
-        <ele>33.833</ele>
-        <time>2007-10-03T16:12:20Z</time>
-        <course>29.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763025000" lon="-0.005721600">
-        <ele>33.833</ele>
-        <time>2007-10-03T16:12:21Z</time>
-        <course>29.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.763066600" lon="-0.005625000">
-        <ele>33.223</ele>
-        <time>2007-10-03T16:12:24Z</time>
-        <course>64.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763074900" lon="-0.005600000">
-        <ele>33.223</ele>
-        <time>2007-10-03T16:12:25Z</time>
-        <course>68.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763096600" lon="-0.005538300">
-        <ele>33.528</ele>
-        <time>2007-10-03T16:12:28Z</time>
-        <course>59.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763103300" lon="-0.005518300">
-        <ele>33.528</ele>
-        <time>2007-10-03T16:12:29Z</time>
-        <course>59.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763130000" lon="-0.005446600">
-        <ele>34.442</ele>
-        <time>2007-10-03T16:12:32Z</time>
-        <course>61.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763140000" lon="-0.005421600">
-        <ele>34.747</ele>
-        <time>2007-10-03T16:12:33Z</time>
-        <course>60.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763168300" lon="-0.005350000">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:12:36Z</time>
-        <course>64.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763176600" lon="-0.005328300">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:12:37Z</time>
-        <course>66.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763198300" lon="-0.005256600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:12:40Z</time>
-        <course>69.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763203300" lon="-0.005231600">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:12:41Z</time>
-        <course>74.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763224900" lon="-0.005168300">
-        <ele>39.014</ele>
-        <time>2007-10-03T16:12:44Z</time>
-        <course>66.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763236600" lon="-0.005125000">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:12:46Z</time>
-        <course>67.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763236600" lon="-0.005125000">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:12:47Z</time>
-        <course>67.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.763265000" lon="-0.005040000">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:12:50Z</time>
-        <course>58.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763273300" lon="-0.005021600">
-        <ele>41.148</ele>
-        <time>2007-10-03T16:12:51Z</time>
-        <course>46.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763305000" lon="-0.004971600">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:12:54Z</time>
-        <course>45.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763314900" lon="-0.004955000">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:12:55Z</time>
-        <course>44.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763350000" lon="-0.004909900">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:12:58Z</time>
-        <course>40.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763359900" lon="-0.004895000">
-        <ele>39.319</ele>
-        <time>2007-10-03T16:12:59Z</time>
-        <course>43.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763391600" lon="-0.004846600">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:13:02Z</time>
-        <course>42.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763403300" lon="-0.004831600">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:13:03Z</time>
-        <course>46.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763438300" lon="-0.004793300">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:13:06Z</time>
-        <course>19.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763453300" lon="-0.004785000">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:13:07Z</time>
-        <course>13.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763501600" lon="-0.004773300">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:13:10Z</time>
-        <course>11.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763518300" lon="-0.004766600">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:13:11Z</time>
-        <course>15.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763551600" lon="-0.004726600">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:13:14Z</time>
-        <course>48.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763569900" lon="-0.004698300">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:13:16Z</time>
-        <course>36.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763590000" lon="-0.004686600">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:13:18Z</time>
-        <course>24.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763611600" lon="-0.004671600">
-        <ele>39.014</ele>
-        <time>2007-10-03T16:13:20Z</time>
-        <course>20.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763623300" lon="-0.004665000">
-        <ele>39.319</ele>
-        <time>2007-10-03T16:13:21Z</time>
-        <course>20.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763633300" lon="-0.004658300">
-        <ele>39.929</ele>
-        <time>2007-10-03T16:13:24Z</time>
-        <course>20.000000</course>
-        <speed>0.000000</speed>
-      </trkpt>
-      <trkpt lat="51.763659900" lon="-0.004631600">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:13:25Z</time>
-        <course>36.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763686600" lon="-0.004583300">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:13:28Z</time>
-        <course>44.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763695000" lon="-0.004568300">
-        <ele>40.538</ele>
-        <time>2007-10-03T16:13:29Z</time>
-        <course>43.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763723300" lon="-0.004520000">
-        <ele>40.234</ele>
-        <time>2007-10-03T16:13:32Z</time>
-        <course>48.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763730000" lon="-0.004503300">
-        <ele>39.929</ele>
-        <time>2007-10-03T16:13:33Z</time>
-        <course>51.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763755000" lon="-0.004455000">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:13:36Z</time>
-        <course>47.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763763300" lon="-0.004438300">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:13:37Z</time>
-        <course>48.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763790000" lon="-0.004390000">
-        <ele>39.014</ele>
-        <time>2007-10-03T16:13:40Z</time>
-        <course>49.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763798300" lon="-0.004373300">
-        <ele>39.014</ele>
-        <time>2007-10-03T16:13:41Z</time>
-        <course>48.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763823300" lon="-0.004323300">
-        <ele>38.100</ele>
-        <time>2007-10-03T16:13:44Z</time>
-        <course>48.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763843300" lon="-0.004295000">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:13:46Z</time>
-        <course>45.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763853300" lon="-0.004279900">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:13:47Z</time>
-        <course>46.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763880000" lon="-0.004233300">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:13:50Z</time>
-        <course>52.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763888300" lon="-0.004216600">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:13:51Z</time>
-        <course>54.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763910000" lon="-0.004166600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:13:54Z</time>
-        <course>54.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.763916600" lon="-0.004146600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:13:55Z</time>
-        <course>58.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763941600" lon="-0.004090000">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:13:58Z</time>
-        <course>51.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763950000" lon="-0.004071600">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:13:59Z</time>
-        <course>55.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763973300" lon="-0.004013300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:14:02Z</time>
-        <course>56.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.763981600" lon="-0.003995000">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:14:03Z</time>
-        <course>54.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764006600" lon="-0.003933300">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:14:06Z</time>
-        <course>55.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764016600" lon="-0.003915000">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:14:07Z</time>
-        <course>51.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764041600" lon="-0.003860000">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:14:10Z</time>
-        <course>56.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764046600" lon="-0.003843300">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:14:11Z</time>
-        <course>60.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764068300" lon="-0.003785000">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:14:14Z</time>
-        <course>55.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764084900" lon="-0.003748300">
-        <ele>35.357</ele>
-        <time>2007-10-03T16:14:16Z</time>
-        <course>55.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764101600" lon="-0.003710000">
-        <ele>35.662</ele>
-        <time>2007-10-03T16:14:18Z</time>
-        <course>61.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764118300" lon="-0.003666600">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:14:20Z</time>
-        <course>62.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764126600" lon="-0.003646600">
-        <ele>36.271</ele>
-        <time>2007-10-03T16:14:21Z</time>
-        <course>59.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764151600" lon="-0.003583300">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:14:24Z</time>
-        <course>60.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764159900" lon="-0.003560000">
-        <ele>37.186</ele>
-        <time>2007-10-03T16:14:25Z</time>
-        <course>57.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764186600" lon="-0.003493300">
-        <ele>39.319</ele>
-        <time>2007-10-03T16:14:28Z</time>
-        <course>60.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764195000" lon="-0.003471600">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:14:29Z</time>
-        <course>61.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764218300" lon="-0.003413300">
-        <ele>39.929</ele>
-        <time>2007-10-03T16:14:32Z</time>
-        <course>55.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764226600" lon="-0.003395000">
-        <ele>39.929</ele>
-        <time>2007-10-03T16:14:33Z</time>
-        <course>59.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764248300" lon="-0.003341600">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:14:36Z</time>
-        <course>54.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764253300" lon="-0.003325000">
-        <ele>39.319</ele>
-        <time>2007-10-03T16:14:37Z</time>
-        <course>56.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764271600" lon="-0.003268300">
-        <ele>38.405</ele>
-        <time>2007-10-03T16:14:40Z</time>
-        <course>62.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764278300" lon="-0.003250000">
-        <ele>37.795</ele>
-        <time>2007-10-03T16:14:41Z</time>
-        <course>61.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764301600" lon="-0.003201600">
-        <ele>36.576</ele>
-        <time>2007-10-03T16:14:44Z</time>
-        <course>35.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764324900" lon="-0.003189900">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:14:46Z</time>
-        <course>11.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764354900" lon="-0.003189900">
-        <ele>35.966</ele>
-        <time>2007-10-03T16:14:48Z</time>
-        <course>346.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764386600" lon="-0.003203300">
-        <ele>36.881</ele>
-        <time>2007-10-03T16:14:50Z</time>
-        <course>341.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764401600" lon="-0.003210000">
-        <ele>37.490</ele>
-        <time>2007-10-03T16:14:51Z</time>
-        <course>334.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764444900" lon="-0.003236600">
-        <ele>38.710</ele>
-        <time>2007-10-03T16:14:54Z</time>
-        <course>335.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764458300" lon="-0.003246600">
-        <ele>39.014</ele>
-        <time>2007-10-03T16:14:55Z</time>
-        <course>335.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764500000" lon="-0.003268300">
-        <ele>39.624</ele>
-        <time>2007-10-03T16:14:58Z</time>
-        <course>349.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764515000" lon="-0.003263300">
-        <ele>39.929</ele>
-        <time>2007-10-03T16:14:59Z</time>
-        <course>11.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764563300" lon="-0.003246600">
-        <ele>41.453</ele>
-        <time>2007-10-03T16:15:02Z</time>
-        <course>2.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764578300" lon="-0.003243300">
-        <ele>42.062</ele>
-        <time>2007-10-03T16:15:03Z</time>
-        <course>5.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764621600" lon="-0.003235000">
-        <ele>42.672</ele>
-        <time>2007-10-03T16:15:06Z</time>
-        <course>1.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764635000" lon="-0.003236600">
-        <ele>42.672</ele>
-        <time>2007-10-03T16:15:07Z</time>
-        <course>354.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764673300" lon="-0.003251600">
-        <ele>42.977</ele>
-        <time>2007-10-03T16:15:10Z</time>
-        <course>348.000000</course>
-        <speed>1.666667</speed>
-      </trkpt>
-      <trkpt lat="51.764686600" lon="-0.003255000">
-        <ele>42.977</ele>
-        <time>2007-10-03T16:15:11Z</time>
-        <course>175.000000</course>
-        <speed>1.111111</speed>
-      </trkpt>
-      <trkpt lat="51.764718300" lon="-0.003238300">
-        <ele>43.586</ele>
-        <time>2007-10-03T16:15:14Z</time>
-        <course>45.000000</course>
-        <speed>0.555556</speed>
-      </trkpt>
-    </trkseg>
-  </trk>
-</gpx>
diff --git a/reference/navilink_tracks.trk b/reference/navilink_tracks.trk
deleted file mode 100644 (file)
index 13ba97f..0000000
Binary files a/reference/navilink_tracks.trk and /dev/null differ
diff --git a/reference/navilink_tracks_gpx.trk b/reference/navilink_tracks_gpx.trk
deleted file mode 100644 (file)
index e03359d..0000000
Binary files a/reference/navilink_tracks_gpx.trk and /dev/null differ
diff --git a/reference/navilink_waypoints.gpx b/reference/navilink_waypoints.gpx
deleted file mode 100644 (file)
index cb8c859..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
-  <time>1970-01-01T00:00:00Z</time>
-  <bounds minlat="51.759301600" minlon="-0.008520000" maxlat="51.775566600" maxlon="0.004690000"/>
-  <wpt lat="51.768668300" lon="0.003845000">
-    <ele>67.970</ele>
-    <time>2007-09-27T13:37:38Z</time>
-    <name>M000</name>
-    <cmt>M000</cmt>
-    <desc>M000</desc>
-    <sym>Star</sym>
-  </wpt>
-  <wpt lat="51.768668300" lon="0.003845000">
-    <ele>67.970</ele>
-    <time>2007-10-03T17:04:53Z</time>
-    <name>M000</name>
-    <cmt>M000</cmt>
-    <desc>M000</desc>
-    <sym>Star</sym>
-  </wpt>
-  <wpt lat="51.775566600" lon="0.004690000">
-    <ele>0.000</ele>
-    <time>2007-09-29T14:45:02Z</time>
-    <name>M001</name>
-    <cmt>M001</cmt>
-    <desc>M001</desc>
-    <sym>Star</sym>
-  </wpt>
-  <wpt lat="51.775566600" lon="0.004690000">
-    <ele>0.000</ele>
-    <time>2007-10-03T17:04:53Z</time>
-    <name>M001</name>
-    <cmt>M001</cmt>
-    <desc>M001</desc>
-    <sym>Star</sym>
-  </wpt>
-  <wpt lat="51.759301600" lon="-0.008520000">
-    <ele>36.271</ele>
-    <time>2007-10-03T16:04:48Z</time>
-    <name>M002</name>
-    <cmt>M002</cmt>
-    <desc>M002</desc>
-    <sym>Star</sym>
-  </wpt>
-  <wpt lat="51.759301600" lon="-0.008520000">
-    <ele>36.271</ele>
-    <time>2007-10-03T17:04:53Z</time>
-    <name>M002</name>
-    <cmt>M002</cmt>
-    <desc>M002</desc>
-    <sym>Star</sym>
-  </wpt>
-  <wpt lat="51.759565000" lon="-0.008035000">
-    <ele>35.357</ele>
-    <time>2007-10-03T16:07:12Z</time>
-    <name>SUBWAY</name>
-    <cmt>SUBWAY</cmt>
-    <desc>SUBWAY</desc>
-    <sym>Star</sym>
-  </wpt>
-  <wpt lat="51.759565000" lon="-0.008035000">
-    <ele>35.357</ele>
-    <time>2007-10-03T17:04:53Z</time>
-    <name>SUBWAY</name>
-    <cmt>SUBWAY</cmt>
-    <desc>SUBWAY</desc>
-    <sym>Star</sym>
-  </wpt>
-</gpx>
diff --git a/reference/navilink_waypoints.wpt b/reference/navilink_waypoints.wpt
deleted file mode 100644 (file)
index 0dd8f06..0000000
Binary files a/reference/navilink_waypoints.wpt and /dev/null differ
diff --git a/reference/navilink_waypoints_gpx.wpt b/reference/navilink_waypoints_gpx.wpt
deleted file mode 100644 (file)
index 13f994b..0000000
Binary files a/reference/navilink_waypoints_gpx.wpt and /dev/null differ
diff --git a/sbn.cc b/sbn.cc
deleted file mode 100644 (file)
index 222cdd5..0000000
--- a/sbn.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
-    Locosys NaviGPS GT-31/BGT-31 SiRF binary logging format (SBN)
-
-    Copyright (C) 2008  Rodney Lorrimar <rodney@rodney.id.au>
-    Copyright (C) 2005  Robert Lipe, robertlipe+source@gpsbabel.org
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-#include <cstring>     // for size_t, memcpy
-
-#include <QDate>       // for QDate
-#include <QDateTime>   // for QDateTime
-#include <QTime>       // for QTime
-#include <QString>     // for QString
-#include <QVector>     // for QVector
-#include <QtGlobal>    // for Q_UNUSED
-#include <Qt>          // for UTC
-
-#include "defs.h"
-#include "gbfile.h"    // for gbfread, gbfclose, gbfeof, gbfopen
-#include "navilink.h"  // for navilink_checksum_packet, locosys_...
-
-
-#define MYNAME "sbn"
-
-static gbfile* file_handle = nullptr;
-
-static
-QVector<arglist_t> sbn_args = {
-};
-
-
-/**********************************************************************/
-
-/* Packets are encoded according to the SiRF Binary Protocol.
- *
- *   http://www.navmanwirelessoem.com/oem/customer-support/oem-ne
- *   ws/product-briefs-and-data-sheets/jupiter-32-xlp-new2/sirf-b
- *   inary-protocol-reference-manual
- *
- * The important packet is "Geodetic Navigation Data" (Message ID 41).
- */
-
-#define PID_SBN              41
-#define SBN_RECORD_LEN       97 /* 91 plus three two shorts added by Locosys */
-/* V1.3 of the s/w added SDOP and and VSDOP bytes */
-#define PID_VISIBLE_LIST     13
-#define PID_QRY_INFORMATION  253
-#define QRY_INFORMATION_LEN  41
-#define INFO_USERNAME_LEN    13
-#define INFO_SERIAL_NUM_LEN  9
-#define INFO_LOG_RATE_LEN    3
-#define INFO_VERSION_LEN     12
-#define INFO_SEP             ','
-
-
-/*
- * Very similar to read_packet in navilink.c, except reads from file
- * instead of serial, and integers are read in big endian order.
- */
-static size_t
-read_packet(int* type, void* payload, size_t max_len)
-{
-  unsigned char start[4];
-
-  if (gbfread(start, sizeof(start), 1, file_handle) != 1) {
-    if (gbfeof(file_handle)) {
-      return 0;
-    }
-
-    fatal(MYNAME ": Format error: No packet start.\n");
-  }
-
-  if (start[0] != 0xa0 || start[1] != 0xa2) {
-    fatal(MYNAME ": Format error: Bad packet start.\n");
-  }
-
-  size_t size = be_readu16(start + 2);
-
-  if (size < 1 || max_len < size) {
-    fatal(MYNAME ": Format error: unexpected size: %d.\n", (int) size);
-  }
-
-  /* allocate space for checksum and trailing 0xb0b3 */
-  size_t data_size = size + 4;
-
-  /* data_size can be up to about 64k */
-  auto* data = (unsigned char*) xmalloc(data_size);
-
-  if (gbfread(data, data_size, 1, file_handle) != 1) {
-    fatal(MYNAME ": Format error: could not read %d bytes.\n",
-          (int) data_size);
-  }
-
-  *type = data[0];
-
-  unsigned int checksum_exp = be_readu16(data + size);
-  unsigned int checksum_act = navilink_checksum_packet(data, size);
-
-  if (checksum_exp != checksum_act) {
-    fatal(MYNAME ": Checksum error - expected %x got %x\n",
-          checksum_exp, checksum_act);
-  }
-
-  if (data[size + 2] != 0xb0 || data[size + 3] != 0xb3) {
-    fatal(MYNAME ": Format error: Bad packet trailer\n");
-  }
-
-  --size;
-
-  memcpy(payload, data + 1, size);
-  xfree(data);
-
-  return size;
-}
-
-#ifdef LOCOSYS_PARSE_FILE_ID
-static size_t
-hdrcpy(char* dest, const char* src, size_t max_len)
-{
-  size_t i;
-
-  for (i = 0; i < max_len && *src != INFO_SEP; i++) {
-    *dest++ = *src++;
-  }
-  *dest++ = 0;
-
-  return ++i;
-}
-#endif /* LOCOSYS_PARSE_FILE_ID */
-
-bool
-locosys_decode_file_id(char* header, size_t len)
-{
-  Q_UNUSED(header);
-  Q_UNUSED(len);
-#ifdef LOCOSYS_PARSE_FILE_ID
-  /*
-   * MID_FILE_ID(0xfd) contains the following payload :
-   *   User Name, Serial Number, Log Rate, Firmware Version
-   *     >field separator:","
-   *     >User Name : MAX CHAR(13)
-   *     >Serial Number : MAX CHAR(8)
-   *     >Log Rate : MAX CHAR 3, 0..255 in seconds
-   *     >Firmware Version  :  MAX CHAR (13)
-   */
-
-  char username[INFO_USERNAME_LEN + 1];
-  char serial_num[INFO_SERIAL_NUM_LEN + 1];
-  char log_rate[INFO_LOG_RATE_LEN + 1];
-  char version[INFO_VERSION_LEN + 1];
-  char* p = header;
-
-  p += hdrcpy(username,   p, INFO_USERNAME_LEN);
-  p += hdrcpy(serial_num, p, INFO_SERIAL_NUM_LEN);
-  p += hdrcpy(log_rate,   p, INFO_LOG_RATE_LEN);
-  p += hdrcpy(version,    p, INFO_VERSION_LEN);
-
-  printf(MYNAME ": Username: %s\n", username);
-  printf(MYNAME ": Serial Number: %s\n", serial_num);
-  printf(MYNAME ": Log rate (seconds): %s\n", log_rate);
-  printf(MYNAME ": Firmware version: %s\n", version);
-#endif /* LOCOSYS_PARSE_FILE_ID */
-
-  return true;
-}
-
-static void
-read_sbn_header(route_head*)
-{
-  char header[QRY_INFORMATION_LEN];
-  int type = 0;
-
-  size_t len = read_packet(&type, header, sizeof(header));
-
-  if (len == 0 || type != PID_QRY_INFORMATION ||
-      !locosys_decode_file_id(header, len)) {
-    fatal(MYNAME ": Format error: Couldn't read SBN header."
-          "This probably isn't a SBN file.\n");
-  }
-}
-
-static int
-is_sbn_valid(const unsigned char* buffer)
-{
-  /* valid navigation (any bit set implies navigation solution is not
-   * optimal) */
-  return !buffer[0] && !buffer[1];
-}
-
-static fix_type
-decode_sbn_mode(const unsigned char* mode)
-{
-  static const fix_type fixes[8] = {
-    fix_none,     /* 000 No Nav */
-    fix_none,     /* 001 1 SV solution */
-    fix_none,     /* 010 2 SV solution */
-    fix_2d,       /* 011 3 SV solution (2D) */
-    fix_3d,       /* 100 4 or more SV solution (3D) */
-    fix_2d,       /* 101 Least Square 2D solution */
-    fix_3d,       /* 110 Least Square 3D solution */
-    fix_none      /* 111 DR solution (no SV) */
-  };
-  int dgps_correction = *mode & 0x80;
-  fix_type fix = fixes[*mode & 7];
-
-  return dgps_correction && fix == fix_3d ? fix_dgps : fix;
-}
-
-static void
-decode_sbn_datetime(const unsigned char* buffer, Waypoint* waypt)
-{
-  int scaled_seconds = be_readu16(buffer + 6);
-
-  int ms = scaled_seconds % 1000;
-  int sec = scaled_seconds / 1000;
-  int min = buffer[5];
-  int hour = buffer[4];
-  int mday = buffer[3];
-  int mon = buffer[2];
-  int year = be_readu16(buffer);
-
-  waypt->SetCreationTime(QDateTime(QDate(year, mon, mday), QTime(hour, min, sec, ms), Qt::UTC));
-}
-
-static void
-decode_sbn_position(const unsigned char* buffer, Waypoint* waypt)
-{
-  waypt->latitude = be_read32(buffer + 0) * 0.0000001;
-  waypt->longitude = be_read32(buffer + 4) * 0.0000001;
-  waypt->altitude = be_read32(buffer + 12) * 0.01;
-}
-
-static Waypoint*
-decode_sbn_record(unsigned char* buffer)
-{
-  auto* waypt = new Waypoint;
-
-  if (is_sbn_valid(buffer)) {
-    waypt->fix = decode_sbn_mode(buffer + 3);
-  } else {
-    waypt->fix = fix_none;
-  }
-
-  decode_sbn_datetime(buffer + 10, waypt);
-  decode_sbn_position(buffer + 22, waypt);
-  waypt->set_speed(be_read16(buffer + 39) * 0.01f);
-  waypt->set_course(be_read16(buffer + 41) * 0.01f);
-  waypt->sat = buffer[87];
-  waypt->hdop = buffer[88] * 0.2f;
-
-  return waypt;
-}
-
-static void
-add_logpoints(route_head* track)
-{
-  unsigned char buffer[SBN_RECORD_LEN];
-  int type = 0;
-
-  while (read_packet(&type, buffer, sizeof(buffer))) {
-    if (type == PID_SBN) {
-      track_add_wpt(track, decode_sbn_record(buffer));
-    } else if (type == PID_VISIBLE_LIST) {
-      /* A list of visible SVs, their IDs, azimuths, elevations.
-       * Not storing this info for now. */
-    } else {
-      warning(MYNAME ": Format error: Unknown packet type 0x%02x.\n", type);
-    }
-  }
-}
-
-/**********************************************************************/
-
-static void
-sbn_rd_init(const QString& fname)
-{
-  file_handle = gbfopen(fname, "r", MYNAME);
-}
-
-static void
-sbn_rd_deinit()
-{
-  gbfclose(file_handle);
-}
-
-static void
-sbn_read()
-{
-  if (global_opts.masked_objective & TRKDATAMASK) {
-    auto* track = new route_head;
-    track_add_head(track);
-
-    read_sbn_header(track);
-
-    add_logpoints(track);
-  }
-}
-
-/**********************************************************************/
-
-/* Characters are always encoded in ASCII. Even if the unit is set
- * to Chinese language, only ASCII characters can be entered.
- */
-
-ff_vecs_t sbn_vecs = {
-  ff_type_file,
-  {
-    ff_cap_none         /* waypoints */,
-    ff_cap_read                                        /* tracks */,
-    ff_cap_none                                        /* routes */
-  },
-  sbn_rd_init,
-  nullptr,
-  sbn_rd_deinit,
-  nullptr,
-  sbn_read,
-  nullptr,
-  nullptr,
-  &sbn_args,
-  NULL_POS_OPS
-};
-/**********************************************************************/
diff --git a/sbp.cc b/sbp.cc
deleted file mode 100644 (file)
index e990713..0000000
--- a/sbp.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-    Locosys NaviGPS GT-31/BGT-31 binary datalog format (SBP)
-
-    Copyright (C) 2008  Rodney Lorrimar <rodney@rodney.id.au>
-    Copyright (C) 2005  Robert Lipe, robertlipe+source@gpsbabel.org
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
- */
-
-#include <cstddef>     // for size_t
-
-#include <QString>     // for QString
-#include <QVector>     // for QVector
-
-#include "defs.h"
-#include "gbfile.h"    // for gbfread, gbfclose, gbfopen, gbfile
-#include "navilink.h"  // for locosys_decode_file_id, navilink_decode_logpoint
-
-
-#define MYNAME "sbp"
-
-static gbfile* file_handle = nullptr;
-
-static
-QVector<arglist_t> sbp_args = {
-};
-
-/*******************************************************************************
-* %%%        global callbacks called by gpsbabel main process              %%% *
-*******************************************************************************/
-
-static void
-sbp_rd_init(const QString& fname)
-{
-  file_handle = gbfopen(fname, "r", MYNAME);
-}
-
-static void
-sbp_rd_deinit()
-{
-  gbfclose(file_handle);
-}
-
-static void
-read_sbp_header(route_head*)
-{
-  /*
-   * A complete SBP file contains 64 bytes header,
-   *
-   * Here is the definition of the SBP header
-   * BYTE 0 ~1 : true SBP header length
-   * BYTE 2~63:  MID_FILE_ID(0xfd)
-   *             will stuff 0xff for remaining bytes
-   */
-
-#define HEADER_SKIP 7
-
-  bool success;
-  char header[64];
-
-  if (gbfread(header, sizeof(header), 1, file_handle) == 1) {
-    size_t len = le_read16(header) - HEADER_SKIP;
-    if (len > sizeof(header)) {
-      len = sizeof(header);
-    }
-
-    success = locosys_decode_file_id(header + HEADER_SKIP, len);
-  } else {
-    success = false;
-  }
-
-  if (!success) {
-    fatal(MYNAME ": Format error: Couldn't read SBP header."
-          "This probably isn't a SBP file.\n");
-  }
-}
-
-static Waypoint*
-read_logpoint()
-{
-  unsigned char buffer[SBP_RECORD_LEN];
-
-  if (gbfread(buffer, sizeof(buffer), 1, file_handle) == 1) {
-    return navilink_decode_logpoint(buffer);
-  }
-
-  return nullptr;
-}
-
-static void
-sbp_read()
-{
-  Waypoint* logpoint;
-
-  auto* track = new route_head;
-  track_add_head(track);
-
-  read_sbp_header(track);
-
-  while ((logpoint = read_logpoint())) {
-    track_add_wpt(track, logpoint);
-  }
-}
-
-/**************************************************************************/
-
-/* ascii is the expected character set */
-/* not fixed, can be changed through command line parameter */
-
-ff_vecs_t sbp_vecs = {
-  ff_type_file,
-  {
-    ff_cap_none         /* waypoints */,
-    ff_cap_read                                        /* tracks */,
-    ff_cap_none                                        /* routes */
-  },
-  sbp_rd_init,
-  nullptr,
-  sbp_rd_deinit,
-  nullptr,
-  sbp_read,
-  nullptr,
-  nullptr,
-  &sbp_args,
-  NULL_POS_OPS
-};
-/**************************************************************************/
diff --git a/testo.d/navilink.test b/testo.d/navilink.test
deleted file mode 100644 (file)
index 8a21f6b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# NaviLink waypoints
-#
-gpsbabel -i navilink -f ${REFERENCE}/navilink_waypoints.wpt -o gpx -F ${TMPDIR}/navilink_waypoints.gpx
-compare ${REFERENCE}/navilink_waypoints.gpx ${TMPDIR}/navilink_waypoints.gpx
-gpsbabel -i gpx -f ${TMPDIR}/navilink_waypoints.gpx -o navilink -F ${TMPDIR}/navilink_waypoints_gpx.wpt
-# not quite what we start with.
-compare ${REFERENCE}/navilink_waypoints_gpx.wpt ${TMPDIR}/navilink_waypoints_gpx.wpt
-
-#
-# NaviLink tracks
-#
-gpsbabel -t -i navilink -f ${REFERENCE}/navilink_tracks.trk -o gpx -F ${TMPDIR}/navilink_tracks.gpx
-compare ${REFERENCE}/navilink_tracks.gpx ${TMPDIR}/navilink_tracks.gpx
-gpsbabel -t -i gpx -f ${TMPDIR}/navilink_tracks.gpx -o navilink -F ${TMPDIR}/navilink_tracks_gpx.trk
-#compare ${REFERENCE}/navilink_tracks_gpx.trk ${TMPDIR}/navilink_tracks_gpx.trk
-
diff --git a/testo.d/sbn.test b/testo.d/sbn.test
deleted file mode 100644 (file)
index 732d47f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# SBN tracks (Locosys NaviGPS)
-#
-gpsbabel -t -i sbn -f ${REFERENCE}/track/sbn.SBN -o gpx -F ${TMPDIR}/sbn.gpx
-compare ${REFERENCE}/track/sbn.gpx ${TMPDIR}/sbn.gpx
-
-# V1.3 of the firmware added two bytes in the packet
-gpsbabel -t -i sbn -f ${REFERENCE}/track/sbn-v13.sbn -o gpx -F ${TMPDIR}/sbn-v13.gpx
-compare ${REFERENCE}/track/sbn-v13.gpx ${TMPDIR}/sbn-v13.gpx
diff --git a/testo.d/sbp.test b/testo.d/sbp.test
deleted file mode 100644 (file)
index 977c149..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# SBP tracks (Locosys NaviGPS)
-#
-gpsbabel -t -i sbp -f ${REFERENCE}/track/datalog.sbp -o gpx -F ${TMPDIR}/datalog.gpx
-compare ${REFERENCE}/track/datalog.gpx ${TMPDIR}/datalog.gpx
-
diff --git a/vecs.cc b/vecs.cc
index 143d1041893c245163d9323f2054a49a05a95056..5665faf867c778f3be25feca754ba12c0e0315b0 100644 (file)
--- a/vecs.cc
+++ b/vecs.cc
@@ -91,9 +91,6 @@ extern ff_vecs_t gtm_vecs;
 extern ff_vecs_t garmin_txt_vecs;
 #endif // CSVFMTS_ENABLED
 extern ff_vecs_t ggv_log_vecs;
-extern ff_vecs_t navilink_vecs;
-extern ff_vecs_t sbp_vecs;
-extern ff_vecs_t sbn_vecs;
 extern ff_vecs_t v900_vecs;
 extern ff_vecs_t format_garmin_xt_vecs;
 #endif // MAXIMAL_ENABLED
@@ -151,13 +148,10 @@ struct Vecs::Impl {
   Dg100FileFormat dg100_ffmt;
   Dg200SerialFormat dg200_fmt;
   Dg200FileFormat dg200_ffmt;
-  LegacyFormat navilink_fmt {navilink_vecs};
   OsmFormat osm_fmt;
   ExifFormat exif_fmt;
   HumminbirdFormat humminbird_fmt;
   HumminbirdHTFormat humminbird_ht_fmt;
-  LegacyFormat sbp_fmt {sbp_vecs};
-  LegacyFormat sbn_fmt {sbn_vecs};
   LegacyFormat v900_fmt {v900_vecs};
   SkytraqFormat skytraq_fmt;
   SkytraqfileFormat skytraq_ffmt;
@@ -400,13 +394,6 @@ struct Vecs::Impl {
       nullptr,
       nullptr,
     },
-    {
-      &navilink_fmt,
-      "navilink",
-      "NaviGPS GT-11/BGT-11 Download",
-      nullptr,
-      nullptr,
-    },
     {
       &osm_fmt,
       "osm",
@@ -435,20 +422,6 @@ struct Vecs::Impl {
       "ht",
       nullptr,
     },
-    {
-      &sbp_fmt,
-      "sbp",
-      "NaviGPS GT-31/BGT-31 datalogger (.sbp)",
-      "sbp",
-      nullptr,
-    },
-    {
-      &sbn_fmt,
-      "sbn",
-      "NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)",
-      "sbn",
-      nullptr,
-    },
     {
       &v900_fmt,
       "v900",
diff --git a/xmldoc/formats/navilink.xml b/xmldoc/formats/navilink.xml
deleted file mode 100644 (file)
index 333ec5a..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<para>
-       GPSBabel supports the Navilink protocol used by the
-       <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.locosystech.com/product.php?zln=en&amp;id=5">Locosys GT-11</link>
-       and
-       <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.locosystech.com/product.php?zln=en&amp;id=30">GT-31</link>
-       GPS receivers. These are sold under a variety of names including:
-<simplelist columns="3" type="vert">
-       <member>NaviGPS</member>
-       <member>NaviGPS-BT</member>
-       <member>GT-11</member>
-       <member>BGT-11</member>
-       <member>GT-31</member>
-       <member>BGT-31</member>
-       <member>Amaryllo</member>
-</simplelist>
-</para>
-<para>
-       This format is used for both the serial protocol used on
-       the USB link and for the files which can be copied from the
-       internal memory to the SD card using recent firmware versions.
-</para>
-<para>
-       If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyUSB0")
-       to be read or written, GPSBabel will use the serial protocol. Specifying
-       a file, either on local filesystem or on a mounted flash card reader,
-       will results in the file-based format being used.
-</para>
-<para>
-       To access the device using the serial protocol over USB the
-       device needs to be in Navilink mode, which can be activated
-       from the main menu of the device. This device uses a Prolific
-       PL2303 USB/Serial adapter internally and that's how it will
-       present itself to the host operating system. You thus need
-       USB drivers for the PL2303, such as those from the 'Download'
-       section of
-       <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.locosystech.com/product.php?zln=en&amp;id=30#">
-       Locosys USB Genie GT-31/BGT-31 drivers
-       </link>.
-</para>
-<para>
-       Details of the Navilink serial protocol can be found
-       <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://notes.splitbrain.org/navilink">here</link>.
-</para>
diff --git a/xmldoc/formats/sbn.xml b/xmldoc/formats/sbn.xml
deleted file mode 100644 (file)
index d748112..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<para>
-       This format is for SBN datalog files saved to the SD card by
-       the Locosys GT-11/BGT-11/GT-31/BGT-31 GPS receivers.
-</para>
-<para>
-       On the device, logging in this format is enabled by choosing
-       SBN from the NMEA ITEMS menu on the MEMORY CARD screen.
-</para>
-<para>
-       Not all data logged in this format is converted by GPSBabel,
-       but the following are:
-
-<simplelist columns="3" type="vert">
-       <member>Position</member>
-       <member>Elevation</member>
-       <member>Time</member>
-       <member>Fix type (2D/3D/DGPS)</member>
-       <member>Speed</member>
-       <member>Course</member>
-       <member>Number of satellites visible</member>
-       <member>Horizontal Dilution of Precision (HDOP)</member>
-</simplelist>
-</para>
-
-<para>
-       The specification of this format can be found in
-       the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.navmanwirelessoem.com/oem/customer-support/oem-news/product-briefs-and-data-sheets/jupiter-32-xlp-new2/sirf-binary-protocol-reference-manual">
-       SiRF Binary Protocol Reference Manual</link>, in the section
-       called Geodetic Navigation Data - Message ID 41.
-</para>
diff --git a/xmldoc/formats/sbp.xml b/xmldoc/formats/sbp.xml
deleted file mode 100644 (file)
index 7d41cb7..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<para>
-       This format is for SBP datalog files saved to the SD card by
-       the Locosys GT-11/BGT-11/GT-31/BGT-31 GPS receivers.
-</para>